diff --git a/Output/RequiredSkinElements.xml b/Output/RequiredSkinElements.xml
new file mode 100644
index 00000000..1d780dc9
--- /dev/null
+++ b/Output/RequiredSkinElements.xml
@@ -0,0 +1,49 @@
+
+
+
+ BG_Default
+ Menu
+ Button
+ CoverTile
+ SelectSlide
+ SelectSlidePlayer
+ SelectSlideArrowLeft
+ SelectSlideArrowRight
+ PopupBG
+ Random
+ ScrollUp
+ ScrollDown
+ Invisible
+ PlayerSelector
+ Plus
+ Minus
+
+
+ BG_Video
+
+
+ Player1
+ Player2
+ Player3
+ Player4
+ Player5
+ Player6
+ BackgroundColor
+ StaticColor
+ StaticWarningColor
+ ButtonColor
+ ButtonSColor
+ ButtonTextColor
+ ButtonTextSColor
+ SelectSlideColor
+ SelectSlideHColor
+ SelectSlideSColor
+ ArrowColor
+ ArrowSColor
+ TextColor
+ TextSColor
+ TextWarningColor
+ Visible
+ Invisible
+
+
\ No newline at end of file
diff --git a/Vocaluxe/Base/CSettings.cs b/Vocaluxe/Base/CSettings.cs
index b5f599de..528b56e1 100644
--- a/Vocaluxe/Base/CSettings.cs
+++ b/Vocaluxe/Base/CSettings.cs
@@ -94,6 +94,8 @@ namespace Vocaluxe.Base
public const string FileNameDebugLog = "Debug.log";
public const string FileNameSongInfoLog = "SongInformation.log";
+ public const string FileNameRequiredSkinElements = "RequiredSkinElements.xml";
+
public const string FileNameSoundT440 = "440Hz.mp3";
public const string FolderNameSongs = "Songs";
diff --git a/Vocaluxe/Base/ThemeSystem/CSkin.cs b/Vocaluxe/Base/ThemeSystem/CSkin.cs
index f4e64ac4..9494d742 100644
--- a/Vocaluxe/Base/ThemeSystem/CSkin.cs
+++ b/Vocaluxe/Base/ThemeSystem/CSkin.cs
@@ -17,10 +17,13 @@ namespace Vocaluxe.Base.ThemeSystem
class CSkin
{
private const int _SkinSystemVersion = 3;
+ private static readonly List _RequiredTextures = new List();
+ private static readonly List _RequiredVideos = new List();
+ private static readonly List _RequiredColors = new List();
private readonly string _Folder;
private readonly string _FileName;
- public readonly int PartyModeID;
+ private readonly CTheme _Parent;
private SInfo _Info;
public String Name
@@ -28,7 +31,7 @@ namespace Vocaluxe.Base.ThemeSystem
get { return _Info.Name; }
}
- public readonly Dictionary Textures = new Dictionary();
+ private readonly Dictionary _Textures = new Dictionary();
private readonly Dictionary _Videos = new Dictionary();
private readonly Dictionary _ColorSchemes = new Dictionary();
@@ -36,16 +39,35 @@ namespace Vocaluxe.Base.ThemeSystem
private bool _IsLoaded;
- public CSkin(string folder, string file, int partyModeId)
+ public static bool InitRequiredElements()
+ {
+ string path = Path.Combine(CSettings.ProgramFolder, CSettings.FileNameRequiredSkinElements);
+ CXMLReader xmlReader = CXMLReader.OpenFile(path);
+ if (xmlReader == null)
+ return false;
+ bool ok = xmlReader.Read("//root/Textures", _RequiredTextures);
+ ok &= xmlReader.Read("//root/Videos", _RequiredVideos);
+ ok &= xmlReader.Read("//root/Colors", _RequiredColors);
+ return ok;
+ }
+
+ public static void Close()
+ {
+ _RequiredTextures.Clear();
+ _RequiredVideos.Clear();
+ _RequiredColors.Clear();
+ }
+
+ public CSkin(string folder, string file, CTheme parent)
{
_Folder = folder;
_FileName = file;
- PartyModeID = partyModeId;
+ _Parent = parent;
}
public override string ToString()
{
- return Name;
+ return _Parent.Name + ":" + Name;
}
#region Load
@@ -62,7 +84,7 @@ namespace Vocaluxe.Base.ThemeSystem
if (!ok)
{
- CLog.LogError("Can't load skin \"" + _FileName + "\". Invalid file!");
+ CLog.LogError("Can't load skin file \"" + _FileName + "\". Invalid file!");
return false;
}
@@ -73,7 +95,7 @@ namespace Vocaluxe.Base.ThemeSystem
{
if (_IsLoaded)
return true;
- Debug.Assert(Textures.Count == 0 && _Videos.Count == 0);
+ Debug.Assert(_Textures.Count == 0 && _Videos.Count == 0);
CXMLReader xmlReader = CXMLReader.OpenFile(Path.Combine(_Folder, _FileName));
if (xmlReader == null)
return false;
@@ -90,7 +112,7 @@ namespace Vocaluxe.Base.ThemeSystem
CLog.LogError("Error on loading texture \"" + name + "\": " + fileName, true);
return false;
}
- Textures.Add(name, texture);
+ _Textures.Add(name, texture);
}
// load videos
@@ -111,19 +133,43 @@ namespace Vocaluxe.Base.ThemeSystem
if (!_LoadColors(xmlReader))
return false;
+ if (!_CheckRequiredElements())
+ return false;
+
_IsLoaded = true;
return true;
}
+ private bool _CheckRequiredElements()
+ {
+ if (_Parent.PartyModeID >= 0)
+ return true;
+ List missingTextures = _RequiredTextures.FindAll(name => !_Textures.ContainsKey(name));
+ List missingVideos = _RequiredVideos.FindAll(name => !_Videos.ContainsKey(name));
+ SColorF dummyColor;
+ List missingColors = _RequiredColors.FindAll(name => !GetColor(name, out dummyColor));
+ if (missingTextures.Count + missingVideos.Count + missingColors.Count == 0)
+ return true;
+ string msg = "The skin \"" + this + "\" is missing the following elements: ";
+ if (missingTextures.Count > 0)
+ msg += Environment.NewLine + "Textures: " + string.Join(", ", missingTextures);
+ if (missingVideos.Count > 0)
+ msg += Environment.NewLine + "Videos: " + string.Join(", ", missingVideos);
+ if (missingColors.Count > 0)
+ msg += Environment.NewLine + "Colors: " + string.Join(", ", missingColors);
+ CLog.LogError(msg);
+ return false;
+ }
+
public void Unload()
{
- foreach (CTextureRef tex in Textures.Values)
+ foreach (CTextureRef tex in _Textures.Values)
tex.Dispose();
foreach (CVideoSkinElement vsk in _Videos.Values)
CVideo.Close(ref vsk.VideoStream);
- Textures.Clear();
+ _Textures.Clear();
_Videos.Clear();
_PlayerColors = null;
_ColorSchemes.Clear();
@@ -133,7 +179,7 @@ namespace Vocaluxe.Base.ThemeSystem
private bool _LoadColors(CXMLReader xmlReader)
{
- if (PartyModeID == -1)
+ if (_Parent.PartyModeID == -1)
{
_PlayerColors = new SColorF[CSettings.MaxNumPlayer];
@@ -160,6 +206,8 @@ namespace Vocaluxe.Base.ThemeSystem
public bool GetColor(string colorName, out SColorF color)
{
+ if (_Parent.Name == "Default" && !_RequiredColors.Contains(colorName))
+ CLog.LogDebug("Non-Default color: " + colorName);
return _ColorSchemes.TryGetValue(colorName, out color) || _GetPlayerColor(colorName, out color);
}
@@ -191,6 +239,7 @@ namespace Vocaluxe.Base.ThemeSystem
public CVideoStream GetVideo(string videoName, bool loop = true)
{
+ Debug.Assert(_Parent.Name != "Default" || _RequiredVideos.Contains(videoName));
CVideoSkinElement sk;
if (_Videos.TryGetValue(videoName, out sk))
{
@@ -206,8 +255,9 @@ namespace Vocaluxe.Base.ThemeSystem
public CTextureRef GetTexture(string name)
{
+ Debug.Assert(_Parent.Name != "Default" || _RequiredTextures.Contains(name));
CTextureRef texture;
- Textures.TryGetValue(name, out texture);
+ _Textures.TryGetValue(name, out texture);
return texture;
}
}
diff --git a/Vocaluxe/Base/ThemeSystem/CTheme.cs b/Vocaluxe/Base/ThemeSystem/CTheme.cs
index 42e37879..eedb2b85 100644
--- a/Vocaluxe/Base/ThemeSystem/CTheme.cs
+++ b/Vocaluxe/Base/ThemeSystem/CTheme.cs
@@ -83,7 +83,7 @@ namespace Vocaluxe.Base.ThemeSystem
ok = false;
foreach (string file in files)
{
- CSkin skin = new CSkin(path, file, PartyModeID);
+ CSkin skin = new CSkin(path, file, this);
if (skin.Init())
{
_Skins.Add(skin.Name, skin);
@@ -133,7 +133,7 @@ namespace Vocaluxe.Base.ThemeSystem
if (skin.Load())
break;
skin.Unload();
- CLog.LogError("Failed to load skin " + Name + ":" + skin + "! Removing...", true);
+ CLog.LogError("Failed to load skin " + skin + "! Removing...", true);
_Skins.Remove(skin.Name);
skin = (PartyModeID == -1 || Name == CSettings.DefaultName) ? _Skins.Values.FirstOrDefault() : null;
}
diff --git a/Vocaluxe/Base/ThemeSystem/CThemes.cs b/Vocaluxe/Base/ThemeSystem/CThemes.cs
index d4814313..03a4facc 100644
--- a/Vocaluxe/Base/ThemeSystem/CThemes.cs
+++ b/Vocaluxe/Base/ThemeSystem/CThemes.cs
@@ -40,13 +40,14 @@ namespace Vocaluxe.Base.ThemeSystem
public static bool Init()
{
- return ReadThemesFromFolder(Path.Combine(CSettings.ProgramFolder, CSettings.FolderNameThemes), -1);
+ return CSkin.InitRequiredElements() && ReadThemesFromFolder(Path.Combine(CSettings.ProgramFolder, CSettings.FolderNameThemes), -1);
}
public static void Close()
{
Unload();
_Themes.Clear();
+ CSkin.Close();
}
public static void Unload()
diff --git a/VocaluxeLib/Xml/CXmlDeserializer.cs b/VocaluxeLib/Xml/CXmlDeserializer.cs
index 11a80d87..9d611c54 100644
--- a/VocaluxeLib/Xml/CXmlDeserializer.cs
+++ b/VocaluxeLib/Xml/CXmlDeserializer.cs
@@ -1,4 +1,7 @@
-using System.Linq;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
namespace VocaluxeLib.Xml
{
@@ -88,6 +91,17 @@ namespace VocaluxeLib.Xml
return result;
}
+ public bool Read(string xPath, List value)
+ {
+ Debug.Assert(value != null);
+ string val;
+ if (!GetValue(xPath, out val))
+ return false;
+ string[] entries = val.Split(new string[] {"\r\n", "\n"}, StringSplitOptions.RemoveEmptyEntries);
+ value.AddRange(entries.Select(s => s.Trim()).Where(s => !string.IsNullOrEmpty(s)));
+ return true;
+ }
+
public bool CheckVersion(string xPath, int reqVersion)
{
int version = 0;