add base class searching for theme elements and metrics
This commit is contained in:
@@ -47,7 +47,7 @@ ScreenSelect::ScreenSelect( CString sClassName ) : Screen(sClassName)
|
|||||||
mc.Load( c, sChoice );
|
mc.Load( c, sChoice );
|
||||||
m_aModeChoices.push_back( mc );
|
m_aModeChoices.push_back( mc );
|
||||||
|
|
||||||
CString sBGAnimationDir = THEME->GetPathTo(BGAnimations, ssprintf("%s %s",m_sName.c_str(),mc.m_sName.c_str()), true); // true="optional"
|
CString sBGAnimationDir = THEME->GetPathTo(BGAnimations, m_sName, mc.m_sName, true); // true="optional"
|
||||||
if( sBGAnimationDir == "" )
|
if( sBGAnimationDir == "" )
|
||||||
sBGAnimationDir = THEME->GetPathToB(m_sName+" background");
|
sBGAnimationDir = THEME->GetPathToB(m_sName+" background");
|
||||||
m_BGAnimations[c].LoadFromAniDir( sBGAnimationDir );
|
m_BGAnimations[c].LoadFromAniDir( sBGAnimationDir );
|
||||||
|
|||||||
@@ -50,6 +50,32 @@ const CString ELEMENT_CATEGORY_STRING[NUM_ELEMENT_CATEGORIES] =
|
|||||||
/* We spend a lot of time doing redundant theme path lookups. Cache results. */
|
/* We spend a lot of time doing redundant theme path lookups. Cache results. */
|
||||||
static map<CString, CString> g_ThemePathCache[NUM_ELEMENT_CATEGORIES];
|
static map<CString, CString> g_ThemePathCache[NUM_ELEMENT_CATEGORIES];
|
||||||
|
|
||||||
|
void FileNameToClassAndElement( const CString &sFileName, CString &sClassNameOut, CString &sElementOut )
|
||||||
|
{
|
||||||
|
// split into class name and file name
|
||||||
|
int iIndexOfFirstSpace = sFileName.Find(" ");
|
||||||
|
if( iIndexOfFirstSpace == -1 ) // no space
|
||||||
|
{
|
||||||
|
sClassNameOut = "";
|
||||||
|
sElementOut = sFileName;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sClassNameOut = sFileName.Left( iIndexOfFirstSpace );
|
||||||
|
sElementOut = sFileName.Right( sFileName.length() - iIndexOfFirstSpace - 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CString ClassAndElementToFileName( const CString &sClassName, const CString &sElement )
|
||||||
|
{
|
||||||
|
if( sClassName.empty() )
|
||||||
|
return sElement;
|
||||||
|
else
|
||||||
|
return sClassName + " " + sElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ThemeManager::ThemeManager()
|
ThemeManager::ThemeManager()
|
||||||
{
|
{
|
||||||
m_pIniMetrics = new IniFile;
|
m_pIniMetrics = new IniFile;
|
||||||
@@ -177,10 +203,9 @@ CString ThemeManager::GetThemeDirFromName( const CString &sThemeName )
|
|||||||
return THEMES_DIR + sThemeName + "/";
|
return THEMES_DIR + sThemeName + "/";
|
||||||
}
|
}
|
||||||
|
|
||||||
CString ThemeManager::GetPathTo( CString sThemeName, ElementCategory category, CString sFileName )
|
CString ThemeManager::GetPathToRaw( CString sThemeName, ElementCategory category, CString sClassName, CString sElement )
|
||||||
{
|
{
|
||||||
try_element_again:
|
try_element_again:
|
||||||
sFileName.MakeLower();
|
|
||||||
|
|
||||||
const CString sThemeDir = GetThemeDirFromName( sThemeName );
|
const CString sThemeDir = GetThemeDirFromName( sThemeName );
|
||||||
const CString sCategory = ELEMENT_CATEGORY_STRING[category];
|
const CString sCategory = ELEMENT_CATEGORY_STRING[category];
|
||||||
@@ -188,22 +213,22 @@ try_element_again:
|
|||||||
CStringArray asElementPaths;
|
CStringArray asElementPaths;
|
||||||
|
|
||||||
// If sFileName already has an extension, we're looking for a specific file
|
// If sFileName already has an extension, we're looking for a specific file
|
||||||
bool bLookingForSpecificFile = sFileName.find_last_of('.') != sFileName.npos;
|
bool bLookingForSpecificFile = sElement.find_last_of('.') != sElement.npos;
|
||||||
bool bDirsOnly = category==BGAnimations;
|
bool bDirsOnly = category==BGAnimations;
|
||||||
|
|
||||||
if( bLookingForSpecificFile )
|
if( bLookingForSpecificFile )
|
||||||
{
|
{
|
||||||
GetDirListing( sThemeDir + sCategory+"/"+sFileName, asElementPaths, bDirsOnly, true );
|
GetDirListing( sThemeDir + sCategory+"/"+ClassAndElementToFileName(sClassName,sElement), asElementPaths, bDirsOnly, true );
|
||||||
}
|
}
|
||||||
else // look for all files starting with sFileName that have types we can use
|
else // look for all files starting with sFileName that have types we can use
|
||||||
{
|
{
|
||||||
/* First, look for redirs. */
|
/* First, look for redirs. */
|
||||||
GetDirListing( sThemeDir + sCategory + "/" + sFileName + ".redir",
|
GetDirListing( sThemeDir + sCategory + "/" + ClassAndElementToFileName(sClassName,sElement) + ".redir",
|
||||||
asElementPaths, false, true );
|
asElementPaths, false, true );
|
||||||
|
|
||||||
const CString wildcard = (category == BGAnimations? "":"*");
|
const CString wildcard = (category == BGAnimations? "":"*");
|
||||||
CStringArray asPaths;
|
CStringArray asPaths;
|
||||||
GetDirListing( sThemeDir + sCategory + "/" + sFileName + wildcard,
|
GetDirListing( sThemeDir + sCategory + "/" + ClassAndElementToFileName(sClassName,sElement) + wildcard,
|
||||||
asPaths, bDirsOnly, true );
|
asPaths, bDirsOnly, true );
|
||||||
|
|
||||||
for( unsigned p = 0; p < asPaths.size(); ++p )
|
for( unsigned p = 0; p < asPaths.size(); ++p )
|
||||||
@@ -238,7 +263,7 @@ try_element_again:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( category == Fonts )
|
if( category == Fonts )
|
||||||
Font::WeedFontNames(asElementPaths, sFileName);
|
Font::WeedFontNames(asElementPaths, ClassAndElementToFileName(sClassName,sElement));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -254,8 +279,8 @@ try_element_again:
|
|||||||
|
|
||||||
CString message = ssprintf(
|
CString message = ssprintf(
|
||||||
"ThemeManager: There is more than one theme element element that matches "
|
"ThemeManager: There is more than one theme element element that matches "
|
||||||
"'%s/%s/%s'. Please remove all but one of these matches.",
|
"'%s/%s/%s %s'. Please remove all but one of these matches.",
|
||||||
sThemeName.c_str(), sCategory.c_str(), sFileName.c_str() );
|
sThemeName.c_str(), sCategory.c_str(), sClassName.c_str(), sElement.c_str() );
|
||||||
|
|
||||||
switch( HOOKS->MessageBoxAbortRetryIgnore(message) )
|
switch( HOOKS->MessageBoxAbortRetryIgnore(message) )
|
||||||
{
|
{
|
||||||
@@ -281,6 +306,9 @@ try_element_again:
|
|||||||
{
|
{
|
||||||
CString sNewFileName = GetRedirContents(sPath);
|
CString sNewFileName = GetRedirContents(sPath);
|
||||||
|
|
||||||
|
CString sNewClassName, sNewFile;
|
||||||
|
FileNameToClassAndElement(sNewFileName, sNewClassName, sNewFile);
|
||||||
|
|
||||||
/* backwards-compatibility hack */
|
/* backwards-compatibility hack */
|
||||||
if( category == Fonts )
|
if( category == Fonts )
|
||||||
sNewFileName.Replace(" 16x16.png", "");
|
sNewFileName.Replace(" 16x16.png", "");
|
||||||
@@ -293,7 +321,7 @@ try_element_again:
|
|||||||
* up resolving to the overridden background. */
|
* up resolving to the overridden background. */
|
||||||
/* Use GetPathToOptional because we don't want report that there's an element
|
/* Use GetPathToOptional because we don't want report that there's an element
|
||||||
* missing. Instead we want to report that the redirect is invalid. */
|
* missing. Instead we want to report that the redirect is invalid. */
|
||||||
CString sNewPath = GetPathTo(category, sNewFileName, true);
|
CString sNewPath = GetPathTo(category, sNewClassName, sNewFile, true);
|
||||||
|
|
||||||
if( !sNewPath.empty() )
|
if( !sNewPath.empty() )
|
||||||
return sNewPath;
|
return sNewPath;
|
||||||
@@ -312,8 +340,10 @@ try_element_again:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CString ThemeManager::GetPathTo( ElementCategory category, CString sFileName, bool bOptional )
|
CString ThemeManager::GetPathTo( ElementCategory category, CString sClassName, CString sElement, bool bOptional )
|
||||||
{
|
{
|
||||||
|
CString sFileName = ClassAndElementToFileName( sClassName, sElement );
|
||||||
|
|
||||||
map<CString, CString> &Cache = g_ThemePathCache[category];
|
map<CString, CString> &Cache = g_ThemePathCache[category];
|
||||||
{
|
{
|
||||||
map<CString, CString>::const_iterator i;
|
map<CString, CString>::const_iterator i;
|
||||||
@@ -326,20 +356,49 @@ CString ThemeManager::GetPathTo( ElementCategory category, CString sFileName, bo
|
|||||||
// TODO: Use HOOKS->MessageBox()
|
// TODO: Use HOOKS->MessageBox()
|
||||||
try_element_again:
|
try_element_again:
|
||||||
|
|
||||||
CString ret = GetPathTo( m_sCurThemeName, category, sFileName);
|
CString sBaseClass;
|
||||||
|
sBaseClass = "";
|
||||||
|
m_pIniMetrics->GetValue(sClassName,"BaseClass",sBaseClass);
|
||||||
|
|
||||||
|
// search the requested current theme and requested class
|
||||||
|
CString ret = GetPathToRaw( m_sCurThemeName, category, sClassName, sElement);
|
||||||
if( !ret.empty() ) // we found something
|
if( !ret.empty() ) // we found something
|
||||||
{
|
{
|
||||||
Cache[sFileName] = ret;
|
Cache[sFileName] = ret;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = GetPathTo( BASE_THEME_NAME, category, sFileName);
|
// search the requested current theme and base class
|
||||||
|
if( !sBaseClass.empty() )
|
||||||
|
{
|
||||||
|
CString ret = GetPathToRaw( m_sCurThemeName, category, sBaseClass, sElement);
|
||||||
|
if( !ret.empty() ) // we found something
|
||||||
|
{
|
||||||
|
Cache[sFileName] = ret;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// search the base theme and requested class
|
||||||
|
ret = GetPathToRaw( BASE_THEME_NAME, category, sClassName, sElement);
|
||||||
if( !ret.empty() ) // we found something
|
if( !ret.empty() ) // we found something
|
||||||
{
|
{
|
||||||
Cache[sFileName] = ret;
|
Cache[sFileName] = ret;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
else if( bOptional )
|
|
||||||
|
// search the base theme and base class
|
||||||
|
if( !sBaseClass.empty() )
|
||||||
|
{
|
||||||
|
ret = GetPathToRaw( BASE_THEME_NAME, category, sBaseClass, sElement);
|
||||||
|
if( !ret.empty() ) // we found something
|
||||||
|
{
|
||||||
|
Cache[sFileName] = ret;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( bOptional )
|
||||||
{
|
{
|
||||||
Cache[sFileName] = "";
|
Cache[sFileName] = "";
|
||||||
return "";
|
return "";
|
||||||
@@ -372,7 +431,7 @@ try_element_again:
|
|||||||
if(sFileName == "_missing")
|
if(sFileName == "_missing")
|
||||||
RageException::Throw("'_missing' isn't present in '%s%s'", GetThemeDirFromName(BASE_THEME_NAME).c_str(), sCategory.c_str() );
|
RageException::Throw("'_missing' isn't present in '%s%s'", GetThemeDirFromName(BASE_THEME_NAME).c_str(), sCategory.c_str() );
|
||||||
|
|
||||||
Cache[sFileName] = GetPathTo( category, "_missing" );
|
Cache[sFileName] = GetPathTo( category, "Common", "missing" );
|
||||||
return Cache[sFileName];
|
return Cache[sFileName];
|
||||||
/* XXX: "abort" and "cancel" are synonyms; merge */
|
/* XXX: "abort" and "cancel" are synonyms; merge */
|
||||||
case ArchHooks::abort:
|
case ArchHooks::abort:
|
||||||
@@ -440,6 +499,10 @@ try_metric_again:
|
|||||||
if( m_pIniMetrics->GetValue(sClassName,sValueName,sValue) )
|
if( m_pIniMetrics->GetValue(sClassName,sValueName,sValue) )
|
||||||
return sValue;
|
return sValue;
|
||||||
|
|
||||||
|
CString sBaseClass;
|
||||||
|
if( m_pIniMetrics->GetValue(sClassName,"BaseClass",sBaseClass) )
|
||||||
|
return GetMetricRaw( sBaseClass, sValueName );
|
||||||
|
|
||||||
CString sMessage = ssprintf( "The theme metric '%s-%s' is missing. Correct this and click Retry, or Cancel to break.",sClassName.c_str(),sValueName.c_str() );
|
CString sMessage = ssprintf( "The theme metric '%s-%s' is missing. Correct this and click Retry, or Cancel to break.",sClassName.c_str(),sValueName.c_str() );
|
||||||
switch( HOOKS->MessageBoxAbortRetryIgnore(sMessage) )
|
switch( HOOKS->MessageBoxAbortRetryIgnore(sMessage) )
|
||||||
{
|
{
|
||||||
@@ -535,3 +598,11 @@ CString ThemeManager::GetLanguageIniPath( CString sThemeName, CString sLanguage
|
|||||||
{
|
{
|
||||||
return GetThemeDirFromName(sThemeName) + LANGUAGES_SUBDIR + sLanguage + ".ini";
|
return GetThemeDirFromName(sThemeName) + LANGUAGES_SUBDIR + sLanguage + ".ini";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: remove these and update the places that use them
|
||||||
|
CString ThemeManager::GetPathToB( CString sFileName, bool bOptional ) { CString sClassName, sElement; FileNameToClassAndElement(sFileName,sClassName,sElement); return GetPathToB(sClassName,sElement,bOptional); }
|
||||||
|
CString ThemeManager::GetPathToF( CString sFileName, bool bOptional ) { CString sClassName, sElement; FileNameToClassAndElement(sFileName,sClassName,sElement); return GetPathToF(sClassName,sElement,bOptional); }
|
||||||
|
CString ThemeManager::GetPathToG( CString sFileName, bool bOptional ) { CString sClassName, sElement; FileNameToClassAndElement(sFileName,sClassName,sElement); return GetPathToG(sClassName,sElement,bOptional); }
|
||||||
|
CString ThemeManager::GetPathToN( CString sFileName, bool bOptional ) { CString sClassName, sElement; FileNameToClassAndElement(sFileName,sClassName,sElement); return GetPathToN(sClassName,sElement,bOptional); }
|
||||||
|
CString ThemeManager::GetPathToS( CString sFileName, bool bOptional ) { CString sClassName, sElement; FileNameToClassAndElement(sFileName,sClassName,sElement); return GetPathToS(sClassName,sElement,bOptional); }
|
||||||
|
CString ThemeManager::GetPathToO( CString sFileName, bool bOptional ) { CString sClassName, sElement; FileNameToClassAndElement(sFileName,sClassName,sElement); return GetPathToO(sClassName,sElement,bOptional); }
|
||||||
|
|||||||
@@ -37,13 +37,22 @@ public:
|
|||||||
void ReloadMetrics();
|
void ReloadMetrics();
|
||||||
void ReloadMetricsIfNecessary();
|
void ReloadMetricsIfNecessary();
|
||||||
|
|
||||||
CString GetPathTo( ElementCategory category, CString sFileName, bool bOptional=false );
|
CString GetPathTo( ElementCategory category, CString sClassName, CString sElement, bool bOptional=false );
|
||||||
CString GetPathToB( CString sFileName, bool bOptional=false ) { return GetPathTo(BGAnimations,sFileName,bOptional); };
|
CString GetPathToB( CString sClassName, CString sElement, bool bOptional=false ) { return GetPathTo(BGAnimations,sClassName,sElement,bOptional); };
|
||||||
CString GetPathToF( CString sFileName, bool bOptional=false ) { return GetPathTo(Fonts,sFileName,bOptional); };
|
CString GetPathToF( CString sClassName, CString sElement, bool bOptional=false ) { return GetPathTo(Fonts,sClassName,sElement,bOptional); };
|
||||||
CString GetPathToG( CString sFileName, bool bOptional=false ) { return GetPathTo(Graphics,sFileName,bOptional); };
|
CString GetPathToG( CString sClassName, CString sElement, bool bOptional=false ) { return GetPathTo(Graphics,sClassName,sElement,bOptional); };
|
||||||
CString GetPathToN( CString sFileName, bool bOptional=false ) { return GetPathTo(Numbers,sFileName,bOptional); };
|
CString GetPathToN( CString sClassName, CString sElement, bool bOptional=false ) { return GetPathTo(Numbers,sClassName,sElement,bOptional); };
|
||||||
CString GetPathToS( CString sFileName, bool bOptional=false ) { return GetPathTo(Sounds,sFileName,bOptional); };
|
CString GetPathToS( CString sClassName, CString sElement, bool bOptional=false ) { return GetPathTo(Sounds,sClassName,sElement,bOptional); };
|
||||||
CString GetPathToO( CString sFileName, bool bOptional=false ) { return GetPathTo(Other,sFileName,bOptional); };
|
CString GetPathToO( CString sClassName, CString sElement, bool bOptional=false ) { return GetPathTo(Other,sClassName,sElement,bOptional); };
|
||||||
|
|
||||||
|
// TODO: remove these and update the places that use them
|
||||||
|
CString GetPathToB( CString sFileName, bool bOptional=false );
|
||||||
|
CString GetPathToF( CString sFileName, bool bOptional=false );
|
||||||
|
CString GetPathToG( CString sFileName, bool bOptional=false );
|
||||||
|
CString GetPathToN( CString sFileName, bool bOptional=false );
|
||||||
|
CString GetPathToS( CString sFileName, bool bOptional=false );
|
||||||
|
CString GetPathToO( CString sFileName, bool bOptional=false );
|
||||||
|
|
||||||
|
|
||||||
bool HasMetric( CString sClassName, CString sValueName );
|
bool HasMetric( CString sClassName, CString sValueName );
|
||||||
CString GetMetricRaw( CString sClassName, CString sValueName );
|
CString GetMetricRaw( CString sClassName, CString sValueName );
|
||||||
@@ -54,7 +63,7 @@ public:
|
|||||||
RageColor GetMetricC( CString sClassName, CString sValueName );
|
RageColor GetMetricC( CString sClassName, CString sValueName );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
CString GetPathTo( CString sThemeName, ElementCategory category, CString sFileName );
|
CString GetPathToRaw( CString sThemeName, ElementCategory category, CString sClassName, CString sFile );
|
||||||
static CString GetThemeDirFromName( const CString &sThemeName );
|
static CString GetThemeDirFromName( const CString &sThemeName );
|
||||||
CString GetElementDir( CString sThemeName );
|
CString GetElementDir( CString sThemeName );
|
||||||
static CString GetMetricsIniPath( CString sThemeName );
|
static CString GetMetricsIniPath( CString sThemeName );
|
||||||
|
|||||||
Reference in New Issue
Block a user