Merge branch 'Automatic_Covers' into develop

Conflicts:
	Vocaluxe/Base/CBackgroundMusic.cs
	VocaluxeLib/Menu/SongMenu/CSongMenuFramework.cs
This commit is contained in:
Flamefire committed 2014-10-02 20:43:17 +02:00
commit f1c89b9a8e
94 files changed
+4513 -3344

No files matched your search

+37
View File
@@ -5,4 +5,41 @@
<Folder>Blue</Folder>
<Author>flokuep</Author>
</Info>
<!--Cover definitions when a category is missing a cover-->
<CoverGenerator1>
<!--Possible types are: Default, Artist, Letter, Edition, Genre, Language, Year, Decade, Date -->
<Type>Default</Type>
<Text>
<!--<Text>: Text to be shown, %TEXT% will be replace by the category name-->
<Text>%TEXT%</Text>
<Font>
<Name>Normal</Name>
<!--<Style>: Text style: Normal, Italic, Bold, BoldItalic-->
<Style>Bold</Style>
<!--<Size> Maximum size of the text in px-->
<Size>500</Size>
</Font>
<!--<Color>: Text color from ColorScheme (high priority)-->
<!--or <R>, <G>, <B>, <A> (lower priority)-->
<Color>
<R>1</R><G>1</G><B>1</B><A>0.8</A>
</Color>
<!--<Margin>: Spacing of the text from the borders of the image in px-->
<Margin>
<Default>24</Default>
<Left>24</Left>
</Margin>
<!--<Indent>: Indentation of the text for multiple lines-->
<Indent>100</Indent>
</Text>
<BackgroundColor>
<R>1</R><G>1</G><B>1</B><A>1</A>
</BackgroundColor>
<!--<Image>: Background image for the cover-->
<Image>EmptyCover.png</Image>
<!--<ShowFirstCover>Whether the first cover of a category should be shown(optional)-->
<ShowFirstCover>true</ShowFirstCover>
<!--<ImageAlpha>Alpha value of the image in case the first cover is shown(optional)-->
<ImageAlpha>0.75</ImageAlpha>
</CoverGenerator1>
</root>
+12 -8
View File
@@ -4,10 +4,12 @@
<Font1>
<Name>Normal</Name>
<Outline>0,00</Outline>
<OutlineColorR>0,00</OutlineColorR>
<OutlineColorG>0,00</OutlineColorG>
<OutlineColorB>0,00</OutlineColorB>
<OutlineColorA>1,00</OutlineColorA>
<OutlineColor>
<R>0,00</R>
<G>0,00</G>
<B>0,00</B>
<A>1,00</A>
</OutlineColor>
<Folder>FreeSans</Folder>
<FileNormal>FreeSans.ttf</FileNormal>
<FileBold>FreeSansBold.ttf</FileBold>
@@ -17,10 +19,12 @@
<Font2>
<Name>Outline</Name>
<Outline>0,10</Outline>
<OutlineColorR>0,00</OutlineColorR>
<OutlineColorG>0,00</OutlineColorG>
<OutlineColorB>0,00</OutlineColorB>
<OutlineColorA>1,00</OutlineColorA>
<OutlineColor>
<R>0,00</R>
<G>0,00</G>
<B>0,00</B>
<A>1,00</A>
</OutlineColor>
<Folder>FreeSans</Folder>
<FileNormal>FreeSans.ttf</FileNormal>
<FileBold>FreeSansBold.ttf</FileBold>
+2 -2
View File
@@ -212,8 +212,8 @@
<string name="TR_SCREENOVIDEO_WEBCAMDEVICES">Webcams</string>
<string name="TR_SCREENOVIDEO_WEBCAMRESOLUTION">Webcam-Resolution</string>
<string name="TR_SCREENOVIDEO_BUTTON_ADJUSTMENTS">Screen adjustments</string>
<string name="TR_SCREENOVIDEOADJUSTMENTS_NOTES">Press CTR + ALT + SHIFT + Arrows to adjust screen</string>
<string name="TR_SCREENOVIDEOADJUSTMENTS_NOTESRESET">CTR + ALT + SHIFT + 0 to reset</string>
<string name="TR_SCREENOVIDEOADJUSTMENTS_NOTES">Press CTR + ALT (+ SHIFT) + Arrows|"+" to adjust screen</string>
<string name="TR_SCREENOVIDEOADJUSTMENTS_NOTESRESET">CTR + ALT + 0 to reset</string>
<string name="TR_SCREENOVIDEOADJUSTMENTS_TOPLEFT">Top left</string>
<string name="TR_SCREENOVIDEOADJUSTMENTS_TOPRIGHT">Top right</string>
<string name="TR_SCREENOVIDEOADJUSTMENTS_BOTTOMLEFT">Bottom left</string>
+2 -2
View File
@@ -211,8 +211,8 @@
<string name="TR_SCREENOVIDEO_WEBCAMDEVICES">Webcams</string>
<string name="TR_SCREENOVIDEO_WEBCAMRESOLUTION">Webcam-Auflösung</string>
<string name="TR_SCREENOVIDEO_BUTTON_ADJUSTMENTS">Anzeigeanpassungen</string>
<string name="TR_SCREENOVIDEOADJUSTMENTS_NOTES">STRG + ALT + SHIFT + Pfeiltasten drücken um den Bildschirm anzupassen</string>
<string name="TR_SCREENOVIDEOADJUSTMENTS_NOTESRESET">STRG + ALT + SHIFT + 0 um die Anpassungen zurückzusetzen</string>
<string name="TR_SCREENOVIDEOADJUSTMENTS_NOTES">STRG + ALT (+ SHIFT) + Pfeiltasten|"+" drücken um den Bildschirm anzupassen</string>
<string name="TR_SCREENOVIDEOADJUSTMENTS_NOTESRESET">STRG + ALT + 0 um die Anpassungen zurückzusetzen</string>
<string name="TR_SCREENOVIDEOADJUSTMENTS_TOPLEFT">Oben links</string>
<string name="TR_SCREENOVIDEOADJUSTMENTS_TOPRIGHT">Oben rechts</string>
<string name="TR_SCREENOVIDEOADJUSTMENTS_BOTTOMLEFT">Unten links</string>
@@ -446,7 +446,7 @@ namespace VocaluxeLib.PartyModes.Challenge
_RoundsTableScrollArea.Y = numberY;
_RoundsTableScrollArea.W = CBase.Settings.GetRenderW() - _Texts[_TextRoundNumber].X - 20;
float delta = _Texts[_TextRoundNumber].Height;
float delta = _Texts[_TextRoundNumber].Rect.H;
//Update statics and texts for rounds
foreach (CRoundsTableRow roundRow in _RoundsTable)
@@ -479,7 +479,7 @@ namespace VocaluxeLib.PartyModes.Challenge
roundRow.TextScores[column].Y = numberY + delta;
roundRow.TextScores[column].MaxWidth = maxw;
}
numberY = numberY + delta + delta;
numberY = numberY + 2*delta;
}
numberY = numberY + delta / 2;
}
@@ -532,7 +532,7 @@ namespace VocaluxeLib.PartyModes.Challenge
_PlayerTableScrollArea = new SRectF {X = _Texts[_TextPosition].X, Y = _Texts[_TextPosition].Y, W = _Texts[_TextGamePoints].X - _Texts[_TextPosition].X};
_PlayerTable = new List<STableRow>();
float delta = _Texts[_TextPosition].Height * 1.2f;
float delta = _Texts[_TextPosition].Rect.H * 1.2f;
float h = 0;
@@ -446,7 +446,7 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
_RoundsTableScrollArea.Y = numberY;
_RoundsTableScrollArea.W = CBase.Settings.GetRenderW() - _Texts[_TextRoundNumber].X - 20;
float delta = _Texts[_TextRoundNumber].Height;
float delta = _Texts[_TextRoundNumber].Rect.H;
//Update statics and texts for rounds
foreach (CRoundsTableRow roundRow in _RoundsTable)
@@ -532,7 +532,7 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
_PlayerTableScrollArea = new SRectF {X = _Texts[_TextPosition].X, Y = _Texts[_TextPosition].Y, W = _Texts[_TextGamePoints].X - _Texts[_TextPosition].X};
_PlayerTable = new List<STableRow>();
float delta = _Texts[_TextPosition].Height * 1.2f;
float delta = _Texts[_TextPosition].Rect.H * 1.2f;
float h = 0;
+28 -18
View File
@@ -52,25 +52,26 @@ namespace Vocaluxe.Base
public static bool VideoEnabled
{
get { return _PlaysPreview ? _PreviewPlayer.VideoEnabled : _SongPlayer.VideoEnabled; }
set {
if(_PlaysPreview)
set
{
if (_PlaysPreview)
_PreviewPlayer.VideoEnabled = value;
else
else
_SongPlayer.VideoEnabled = value;
}
}
public static bool CanSing
{
get
public static bool CanSing
{
get
{
if (_PlaysPreview)
return false;
else if (_BGMusicFiles.Contains(_CurrentPlaylistElement))
return false;
else
if (_BGMusicFiles.Contains(_CurrentPlaylistElement))
return false;
else return true;
}
return true;
}
}
public static bool Disabled
@@ -85,7 +86,8 @@ namespace Vocaluxe.Base
}
}
public static bool RepeatSong {
public static bool RepeatSong
{
get { return _SongPlayer.RepeatSong; }
set { _SongPlayer.RepeatSong = value; }
}
@@ -100,13 +102,20 @@ namespace Vocaluxe.Base
get { return _SongPlayer.SongHasVideo; }
}
public static bool IsPlaying { get { return _PlaysPreview ? _PreviewPlayer.IsPlaying : _SongPlayer.IsPlaying; } }
public static bool IsPlaying
{
get { return _PlaysPreview ? _PreviewPlayer.IsPlaying : _SongPlayer.IsPlaying; }
}
public static bool IsPlayingPreview { get { return _PlaysPreview; } }
public static bool IsPlayingPreview
{
get { return _PlaysPreview; }
}
public static string ArtistAndTitle
{
get {
get
{
if (_PlaysPreview)
return _PreviewPlayer.ArtistAndTitle;
else
@@ -119,7 +128,7 @@ namespace Vocaluxe.Base
get { return _PlaysPreview ? _PreviewPlayer.Length : _SongPlayer.Length; }
}
public static CTexture Cover
public static CTextureRef Cover
{
get { return _PlaysPreview ? _PreviewPlayer.Cover : _SongPlayer.Cover; }
}
@@ -185,11 +194,13 @@ namespace Vocaluxe.Base
if (_PlaysPreview)
_PreviewPlayer.Play();
else if(CConfig.BackgroundMusic == EBackgroundMusicOffOn.TR_CONFIG_ON)
{
if (_SongPlayer.SongLoaded)
//Resume
_SongPlayer.TogglePause();
else
Next();
}
}
public static void Stop()
@@ -278,7 +289,7 @@ namespace Vocaluxe.Base
public static void Update()
{
if (!IsPlaying && (!_SongPlayer.SongLoaded || !_PreviewPlayer.SongLoaded) )
if (!IsPlaying && (!_SongPlayer.SongLoaded || !_PreviewPlayer.SongLoaded))
return;
if (_PlaysPreview)
@@ -291,7 +302,7 @@ namespace Vocaluxe.Base
}
}
public static CTexture GetVideoTexture()
public static CTextureRef GetVideoTexture()
{
return _PlaysPreview ? _PreviewPlayer.GetVideoTexture() : _SongPlayer.GetVideoTexture();
}
@@ -439,6 +450,5 @@ namespace Vocaluxe.Base
{
return _BGMusicFiles.Contains(element);
}
}
}
+8 -1
View File
@@ -28,6 +28,7 @@ using Vocaluxe.Lib.Sound.Record;
using Vocaluxe.Lib.Webcam;
using VocaluxeLib;
using VocaluxeLib.Profile;
using VocaluxeLib.Xml;
namespace Vocaluxe.Base
{
@@ -72,6 +73,8 @@ namespace Vocaluxe.Base
public static int BorderTop;
public static int BorderBottom;
public static EGeneralAlignment ScreenAlignment = EGeneralAlignment.Middle;
public static EAntiAliasingModes AAMode = EAntiAliasingModes.X0;
public static EOffOn VSync = EOffOn.TR_CONFIG_ON;
@@ -226,6 +229,8 @@ namespace Vocaluxe.Base
xmlReader.TryGetIntValue("//root/Graphics/ScreenW", ref ScreenW);
xmlReader.TryGetIntValue("//root/Graphics/ScreenH", ref ScreenH);
xmlReader.TryGetEnumValue("//root/Graphics/ScreenAlignment", ref ScreenAlignment);
xmlReader.TryGetIntValue("//root/Graphics/BorderLeft", ref BorderLeft);
xmlReader.TryGetIntValue("//root/Graphics/BorderRight", ref BorderRight);
xmlReader.TryGetIntValue("//root/Graphics/BorderTop", ref BorderTop);
@@ -404,6 +409,8 @@ namespace Vocaluxe.Base
writer.WriteElementString("ScreenW", ScreenW.ToString());
writer.WriteElementString("ScreenH", ScreenH.ToString());
writer.WriteElementString("ScreenAlignment", Enum.GetName(typeof(EGeneralAlignment), ScreenAlignment));
writer.WriteComment("Screen borders (pixels)");
writer.WriteElementString("BorderLeft", BorderLeft.ToString());
writer.WriteElementString("BorderRight", BorderRight.ToString());
@@ -834,7 +841,7 @@ namespace Vocaluxe.Base
break;
case "oldtheme":
if(value == "yes")
if (value == "yes")
LoadOldThemeFiles = true;
break;
}
+103 -17
View File
@@ -17,25 +17,31 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Threading.Tasks;
using VocaluxeLib;
using VocaluxeLib.Draw;
using VocaluxeLib.Songs;
using VocaluxeLib.Xml;
namespace Vocaluxe.Base
{
struct SCoverTheme
struct SThemeCover
{
public string Name;
public string Folder;
public string File;
public string Name, Folder;
public string FilePath;
}
static class CCover
{
private static readonly Dictionary<string, CTexture> _Covers = new Dictionary<string, CTexture>();
private static readonly List<SCoverTheme> _CoverThemes = new List<SCoverTheme>();
private const string _NoCoverName = "No Cover";
private const string _NoCoverNameAlt = "NoCover";
private static readonly Dictionary<string, CTextureRef> _Covers = new Dictionary<string, CTextureRef>();
private static readonly Dictionary<ECoverGeneratorType, CNoCoverGenerator> _NoCoverGenerators = new Dictionary<ECoverGeneratorType, CNoCoverGenerator>();
private static readonly List<SThemeCover> _CoverThemes = new List<SThemeCover>();
public static CTexture NoCover { get; private set; }
public static CTextureRef NoCover { get; private set; }
public static void Init()
{
@@ -81,7 +87,7 @@ namespace Vocaluxe.Base
/// <summary>
/// Returns a STexture for a given cover name. Returns "NoCover" if the cover does not exist.
/// </summary>
public static CTexture Cover(string name)
public static CTextureRef Cover(string name)
{
lock (_Covers)
{
@@ -92,6 +98,26 @@ namespace Vocaluxe.Base
}
}
public static CTextureRef GenerateCover(string text, ESongSorting sorting, CCategory category)
{
CSong firstSong = category.GetSong(0);
CTextureRef texture = CDraw.CopyTexture(NoCover);
Task.Factory.StartNew(() =>
{
ECoverGeneratorType type = _SongSortingToType(sorting);
Bitmap coverBmp = !_NoCoverGenerators.ContainsKey(type)?null:_NoCoverGenerators[type].GetCover(text, firstSong != null ? Path.Combine(firstSong.Folder, firstSong.CoverFileName) : null);
if (coverBmp == null && _NoCoverGenerators.ContainsKey(ECoverGeneratorType.Default))
coverBmp = _NoCoverGenerators[ECoverGeneratorType.Default].GetCover(text, firstSong != null ? Path.Combine(firstSong.Folder, firstSong.CoverFileName) : null);
if (coverBmp != null)
CDraw.EnqueueTextureUpdate(texture, coverBmp);
});
lock (_Covers)
{
_Covers.Add(text, texture);
}
return texture;
}
/// <summary>
/// Returns true if a cover with the given name exists.
/// MUST HOLD _Covers lock at this point
@@ -116,24 +142,28 @@ namespace Vocaluxe.Base
{
foreach (string key in _Covers.Keys)
{
CTexture texture = _Covers[key];
CTextureRef texture = _Covers[key];
CDraw.RemoveTexture(ref texture);
}
_Covers.Clear();
}
lock (_NoCoverGenerators)
{
_NoCoverGenerators.Clear();
}
}
/// <summary>
/// Returns a SCoverTheme by cover-theme-name
/// </summary>
private static SCoverTheme _CoverTheme(string coverThemeName)
private static SThemeCover _CoverTheme(string coverThemeName)
{
for (int i = 0; i < _CoverThemes.Count; i++)
{
if (_CoverThemes[i].Name == coverThemeName)
return _CoverThemes[i];
}
return new SCoverTheme();
return new SThemeCover();
}
/// <summary>
@@ -152,14 +182,14 @@ namespace Vocaluxe.Base
if (xmlReader != null)
{
var coverTheme = new SCoverTheme();
var coverTheme = new SThemeCover();
xmlReader.GetValue("//root/Info/Name", out coverTheme.Name, String.Empty);
xmlReader.GetValue("//root/Info/Folder", out coverTheme.Folder, String.Empty);
if (coverTheme.Folder != "" && coverTheme.Name != "")
{
coverTheme.File = file;
coverTheme.FilePath = xmlReader.FilePath;
_CoverThemes.Add(coverTheme);
}
@@ -168,11 +198,11 @@ namespace Vocaluxe.Base
}
/// <summary>
/// Loads all cover which are defined in the cover config file.
/// Loads all covers from the theme
/// </summary>
private static void _LoadCovers(string coverThemeName)
{
SCoverTheme coverTheme = _CoverTheme(coverThemeName);
SThemeCover coverTheme = _CoverTheme(coverThemeName);
if (String.IsNullOrEmpty(coverTheme.Name))
return;
@@ -184,8 +214,64 @@ namespace Vocaluxe.Base
{
foreach (string file in files)
_AddCover(Path.GetFileNameWithoutExtension(file), file);
if (_CoverExists("No Cover"))
NoCover = _Covers["No Cover"];
if (_CoverExists(_NoCoverName))
NoCover = _Covers[_NoCoverName];
else if (_CoverExists(_NoCoverNameAlt))
NoCover = _Covers[_NoCoverNameAlt];
else
CBase.Log.LogError("Covertheme \"" + coverThemeName + "\" does not include a cover file named \"" + _NoCoverName + "\" and cannot be used!", true, true);
}
_LoadNoCoverThemes(coverTheme);
}
private static ECoverGeneratorType _SongSortingToType(ESongSorting sorting)
{
switch (sorting)
{
case ESongSorting.TR_CONFIG_NONE:
return ECoverGeneratorType.Default;
case ESongSorting.TR_CONFIG_FOLDER:
return ECoverGeneratorType.Folder;
case ESongSorting.TR_CONFIG_ARTIST:
return ECoverGeneratorType.Artist;
case ESongSorting.TR_CONFIG_ARTIST_LETTER:
case ESongSorting.TR_CONFIG_TITLE_LETTER:
return ECoverGeneratorType.Letter;
case ESongSorting.TR_CONFIG_EDITION:
return ECoverGeneratorType.Edition;
case ESongSorting.TR_CONFIG_GENRE:
return ECoverGeneratorType.Genre;
case ESongSorting.TR_CONFIG_LANGUAGE:
return ECoverGeneratorType.Language;
case ESongSorting.TR_CONFIG_YEAR:
return ECoverGeneratorType.Year;
case ESongSorting.TR_CONFIG_DECADE:
return ECoverGeneratorType.Decade;
case ESongSorting.TR_CONFIG_DATEADDED:
return ECoverGeneratorType.Date;
default:
throw new ArgumentOutOfRangeException("sorting");
}
}
private static void _LoadNoCoverThemes(SThemeCover coverTheme)
{
CXMLReader xmlReader = CXMLReader.OpenFile(coverTheme.FilePath);
string coverPath = Path.Combine(CSettings.ProgramFolder, CSettings.FolderNameCover, coverTheme.Folder);
lock (_NoCoverGenerators)
{
int i = 1;
while(xmlReader.ItemExists("//root/CoverGenerator"+i)){
SThemeCoverGenerator theme;
if (xmlReader.Read("//root/CoverGenerator" + i, out theme))
{
if (_NoCoverGenerators.ContainsKey(theme.Type))
continue;
CNoCoverGenerator el = new CNoCoverGenerator(theme, coverPath);
_NoCoverGenerators.Add(theme.Type, el);
}
i++;
}
}
}
+1 -1
View File
@@ -27,7 +27,7 @@ namespace Vocaluxe.Base
{
private int _MouseMoveDiffMin = CSettings.MouseMoveDiffMinActive;
private CFading _Fading;
private CTexture _Cursor;
private CTextureRef _Cursor;
private Point _LastDiffPos;
private readonly Stopwatch _Movetimer = new Stopwatch();
+2 -2
View File
@@ -93,7 +93,7 @@ namespace Vocaluxe.Base
_HighscoreDB.IncreaseSongCounter(dataBaseSongID);
}
public static bool GetCover(string fileName, ref CTexture tex, int maxSize)
public static bool GetCover(string fileName, ref CTextureRef tex, int maxSize)
{
return _CoverDB.GetCover(fileName, ref tex, maxSize);
}
@@ -103,7 +103,7 @@ namespace Vocaluxe.Base
_CoverDB.CommitCovers();
}
public static bool GetCreditsRessource(string fileName, ref CTexture tex)
public static bool GetCreditsRessource(string fileName, ref CTextureRef tex)
{
return _ResourceDB.GetCreditsRessource(fileName, ref tex);
}
+254 -83
View File
@@ -20,7 +20,6 @@ using System.Drawing;
using Vocaluxe.Lib.Draw;
using VocaluxeLib;
using VocaluxeLib.Draw;
using VocaluxeLib.Menu;
namespace Vocaluxe.Base
{
@@ -28,6 +27,10 @@ namespace Vocaluxe.Base
{
private static IDraw _Draw;
/// <summary>
/// Initializes the Driver selected in the config
/// </summary>
/// <returns></returns>
public static bool Init()
{
if (_Draw != null)
@@ -74,12 +77,20 @@ namespace Vocaluxe.Base
return _Draw.Init();
}
/// <summary>
/// Has to be called to start rendering <br />
/// Will only return if program is closed <br />
/// Also inits the first screen
/// </summary>
public static void MainLoop()
{
CGraphics.InitFirstScreen();
_Draw.MainLoop();
}
/// <summary>
/// Unloads the current driver, e.g. to switch to another one
/// </summary>
public static void Unload()
{
if (_Draw != null)
@@ -89,143 +100,303 @@ namespace Vocaluxe.Base
}
}
/// <summary>
/// Gets the width of the rendering area
/// </summary>
/// <returns></returns>
public static int GetScreenWidth()
{
return _Draw.GetScreenWidth();
}
/// <summary>
/// Gets the height of the rendering area
/// </summary>
/// <returns></returns>
public static int GetScreenHeight()
{
return _Draw.GetScreenHeight();
}
public static void DrawLine(int a, int r, int g, int b, int w, int x1, int y1, int x2, int y2)
{
_Draw.DrawLine(a, r, g, b, w, x1, y1, x2, y2);
}
public static void DrawRect(SColorF color, SRectF rect, float thickness)
{
if (thickness <= 0f)
return;
_Draw.DrawColor(color, new SRectF(rect.X - thickness / 2, rect.Y - thickness / 2, rect.W + thickness, thickness, rect.Z));
_Draw.DrawColor(color, new SRectF(rect.X - thickness / 2, rect.Y + rect.H - thickness / 2, rect.W + thickness, thickness, rect.Z));
_Draw.DrawColor(color, new SRectF(rect.X - thickness / 2, rect.Y - thickness / 2, thickness, rect.H + thickness, rect.Z));
_Draw.DrawColor(color, new SRectF(rect.X + rect.W - thickness / 2, rect.Y - thickness / 2, thickness, rect.H + thickness, rect.Z));
}
public static void DrawColor(SColorF color, SRectF rect)
{
_Draw.DrawColor(color, rect);
}
public static void DrawColorReflection(SColorF color, SRectF rect, float space, float height)
{
_Draw.DrawColorReflection(color, rect, space, height);
}
public static void ClearScreen()
{
_Draw.ClearScreen();
}
public static CTexture CopyScreen()
{
return _Draw.CopyScreen();
}
public static void CopyScreen(ref CTexture texture)
{
_Draw.CopyScreen(ref texture);
}
/// <summary>
/// Takes a screenshot and saves it to the Screenshot folder
/// </summary>
public static void MakeScreenShot()
{
_Draw.MakeScreenShot();
}
public static CTexture AddTexture(Bitmap bitmap)
/// <summary>
/// Gets the current screen content as a texture
/// </summary>
/// <returns></returns>
public static CTextureRef CopyScreen()
{
return _Draw.CopyScreen();
}
/// <summary>
/// Gets the current screen content updating the given texture
/// </summary>
/// <param name="texture"></param>
public static void CopyScreen(ref CTextureRef texture)
{
_Draw.CopyScreen(ref texture);
}
/// <summary>
/// Adds a texture from a Bitmap and returns a reference to it<br />
/// Must be called from main thread!
/// </summary>
/// <param name="bitmap"></param>
/// <returns>Reference to texture</returns>
public static CTextureRef AddTexture(Bitmap bitmap)
{
return _Draw.AddTexture(bitmap);
}
public static CTexture AddTexture(string texturePath)
/// <summary>
/// Adds a texture from an image file given by its file path<br />
/// Must be called from main thread!
/// </summary>
/// <param name="texturePath"></param>
/// <returns>Reference to texture or null on error</returns>
public static CTextureRef AddTexture(string texturePath)
{
return _Draw.AddTexture(texturePath);
}
public static CTexture AddTexture(int w, int h, byte[] data)
/// <summary>
/// Adds a texture from a byte array<br />
/// Must be called from main thread!
/// </summary>
/// <param name="w">Width of the image</param>
/// <param name="h">Height of the image</param>
/// <param name="data">Array of 4 byte values for each pixel</param>
/// <returns>Reference to texture</returns>
public static CTextureRef AddTexture(int w, int h, byte[] data)
{
return _Draw.AddTexture(w, h, data);
}
public static CTexture EnqueueTexture(int w, int h, byte[] data)
/// <summary>
/// Requests aadding a texture from a byte array <br />
/// Use this if you add textures from another thread or don't need it immediatelly
/// </summary>
/// <param name="w">Width of the image</param>
/// <param name="h">Height of the image</param>
/// <param name="data">Array of 4 byte values for each pixel</param>
/// <returns>Reference to texture</returns>
public static CTextureRef EnqueueTexture(int w, int h, byte[] data)
{
return _Draw.EnqueueTexture(w, h, data);
}
public static bool UpdateTexture(CTexture texture, int w, int h, byte[] data)
/// <summary>
/// Requests adding a texture from a bitmap <br />
/// Use this if you add textures from another thread or don't need it immediatelly
/// </summary>
/// <param name="bmp">Bitmap to add, gets disposed after adding!</param>
/// <returns>Reference to texture</returns>
public static CTextureRef EnqueueTexture(Bitmap bmp)
{
return _Draw.UpdateTexture(texture, w, h, data);
return _Draw.EnqueueTexture(bmp);
}
public static bool UpdateOrAddTexture(ref CTexture texture, int w, int h, byte[] data)
/// <summary>
/// Requests adding a texture from a file <br />
/// Use this if you add textures from another thread or don't need it immediatelly
/// </summary>
/// <param name="texturePath">Full path to the image file</param>
/// <returns>Reference to texture</returns>
public static CTextureRef EnqueueTexture(String texturePath)
{
return _Draw.UpdateOrAddTexture(ref texture, w, h, data);
return _Draw.EnqueueTexture(texturePath);
}
public static void RemoveTexture(ref CTexture texture)
/// <summary>
/// Requests updating a texture from a bitmap<br />
/// Use this if you add textures from another thread or don't need it immediatelly <br />
/// Bitmap is freed after use
/// </summary>
/// <param name="textureRef">Reference to the texture to update</param>
/// <param name="bmp"></param>
public static void EnqueueTextureUpdate(CTextureRef textureRef, Bitmap bmp)
{
_Draw.RemoveTexture(ref texture);
_Draw.EnqueueTextureUpdate(textureRef, bmp);
}
public static void DrawTexture(CTexture texture)
/// <summary>
/// Creates a copy of the texture <br />
/// Updates to the copy do not affect the original texture
/// </summary>
/// <param name="textureRef">Original texture reference</param>
/// <returns>New texture reference of the copy</returns>
public static CTextureRef CopyTexture(CTextureRef textureRef)
{
_Draw.DrawTexture(texture);
return _Draw.CopyTexture(textureRef);
}
public static void DrawTexture(CTexture texture, SRectF rect)
/// <summary>
/// Updates a texture, filling it with the new data
/// </summary>
/// <param name="textureRef"></param>
/// <param name="w">Width of the image</param>
/// <param name="h">Height of the image</param>
/// <param name="data">Array of 4 byte values for each pixel</param>
public static void UpdateTexture(CTextureRef textureRef, int w, int h, byte[] data)
{
_Draw.DrawTexture(texture, rect);
_Draw.UpdateTexture(textureRef, w, h, data);
}
public static void DrawTexture(CTexture texture, SRectF rect, SColorF color, bool mirrored = false)
/// <summary>
/// Updates a texture, filling it with the new data from the bitmap
/// </summary>
/// <param name="textureRef"></param>
/// <param name="bmp"></param>
public static void UpdateTexture(CTextureRef textureRef, Bitmap bmp)
{
_Draw.DrawTexture(texture, rect, color, mirrored);
_Draw.UpdateTexture(textureRef, bmp);
}
public static void DrawTexture(CTexture texture, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false)
/// <summary>
/// Removes a texture from the VRAM and sets it to null to avoid accidential usage <br />
/// Note: You can also use its Dispose method to do the same as this gets automaticly called from the Dispose method and destructor of a texture reference
/// </summary>
/// <param name="texture"></param>
public static void RemoveTexture(ref CTextureRef texture)
{
_Draw.DrawTexture(texture, rect, color, bounds, mirrored);
}
public static void DrawTexture(CTexture texture, SRectF rect, SColorF color, float begin, float end)
{
_Draw.DrawTexture(texture, rect, color, begin, end);
}
public static void DrawTexture(CStatic staticBounds, CTexture texture, EAspect aspect)
{
if (texture == null)
return;
var bounds = new RectangleF(staticBounds.Rect.X, staticBounds.Rect.Y, staticBounds.Rect.W, staticBounds.Rect.H);
RectangleF rect;
CHelper.SetRect(bounds, out rect, texture.OrigAspect, aspect);
DrawTexture(texture, new SRectF(rect.X, rect.Y, rect.Width, rect.Height, staticBounds.Rect.Z),
texture.Color, new SRectF(bounds.X, bounds.Y, bounds.Width, bounds.Height, 0f));
}
public static void DrawTextureReflection(CTexture texture, SRectF rect, SColorF color, SRectF bounds, float space, float height)
{
_Draw.DrawTextureReflection(texture, rect, color, bounds, space, height);
// Disposed textures call this, possibly at program end!
if (_Draw != null)
_Draw.RemoveTexture(ref texture);
}
/// <summary>
/// Returns the number of textures in the VRAM (textures might get reused so this might not be the actual number of textures in use)
/// </summary>
/// <returns></returns>
public static int TextureCount()
{
return _Draw.GetTextureCount();
}
/// <summary>
/// Draws a simple (filled) rectangle with the given color
/// </summary>
/// <param name="color"></param>
/// <param name="rect"></param>
public static void DrawRect(SColorF color, SRectF rect)
{
_Draw.DrawRect(color, rect);
}
/// <summary>
/// Draws the reflection of a filled rectangle with the given color
/// </summary>
/// <param name="color"></param>
/// <param name="rect">(Original) rectangle to draw the reflection for</param>
/// <param name="space">Spacing between the rect and the reflection</param>
/// <param name="height">Height of the reflection</param>
public static void DrawRectReflection(SColorF color, SRectF rect, float space, float height)
{
_Draw.DrawRectReflection(color, rect, space, height);
}
/// <summary>
/// Draws a texture at its position and with its color
/// </summary>
/// <param name="texture">The texture to be drawn</param>
public static void DrawTexture(CTextureRef texture)
{
DrawTexture(texture, texture.Rect);
}
/// <summary>
/// Draws a texture with its color at the given position
/// </summary>
/// <param name="textureRef">The texture to be drawn</param>
/// <param name="rect">A rectangle with the destination coordinates</param>
public static void DrawTexture(CTextureRef textureRef, SRectF rect)
{
DrawTexture(textureRef, rect, textureRef.Color);
}
/// <summary>
/// Draws a texture at the given position with the given color
/// </summary>
/// <param name="textureRef"></param>
/// <param name="rect"></param>
/// <param name="color"></param>
/// <param name="mirrored">True to mirror the texture on the y axis</param>
public static void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, bool mirrored = false)
{
_Draw.DrawTexture(textureRef, rect, color, mirrored);
}
/// <summary>
/// Draws a texture at the given position with the given color
/// </summary>
/// <param name="textureRef"></param>
/// <param name="rect"></param>
/// <param name="color"></param>
/// <param name="bounds">Bounds to draw the texture in (rest gets cropped off)</param>
/// <param name="mirrored">True to mirror the texture on the y axis</param>
public static void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false)
{
_Draw.DrawTexture(textureRef, rect, color, bounds, mirrored);
}
/// <summary>
/// Draws a part of a texture at the given position with the given color
/// </summary>
/// <param name="textureRef"></param>
/// <param name="rect"></param>
/// <param name="color"></param>
/// <param name="begin">Normalized start x-coordinate (0..1)</param>
/// <param name="end">Normalized end x-coordinate (0..1)</param>
public static void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, float begin, float end)
{
_Draw.DrawTexture(textureRef, rect, color, begin, end);
}
/// <summary>
/// Draws a texture fitting it within the given bounds with the method specified by aspect
/// </summary>
/// <param name="textureRef"></param>
/// <param name="bounds">Where to draw the texture</param>
/// <param name="aspect">How to fit a texture in the bounds if the size differs</param>
public static void DrawTexture(CTextureRef textureRef, SRectF bounds, EAspect aspect)
{
DrawTexture(textureRef, bounds, aspect, textureRef.Color);
}
/// <summary>
/// Draws a texture fitting it within the given color and bounds with the method specified by aspect
/// </summary>
/// <param name="textureRef"></param>
/// <param name="bounds">Where to draw the texture</param>
/// <param name="aspect">How to fit a texture in the bounds if the size differs</param>
/// <param name="color">Color to use</param>
public static void DrawTexture(CTextureRef textureRef, SRectF bounds, EAspect aspect, SColorF color)
{
if (textureRef == null)
return;
SRectF rect = CHelper.FitInBounds(bounds, textureRef.OrigAspect, aspect);
DrawTexture(textureRef, rect, color);
}
/// <summary>
/// Draws the reflection of a texture at the given position and with the given color
/// </summary>
/// <param name="textureRef"></param>
/// <param name="rect">(Original) rectangle to draw the reflection for</param>
/// <param name="color"></param>
/// <param name="space">Spacing between the rect and the reflection</param>
/// <param name="height">Height of the reflection</param>
public static void DrawTextureReflection(CTextureRef textureRef, SRectF rect, SColorF color, float space, float height)
{
_Draw.DrawTextureReflection(textureRef, rect, color, space, height);
}
}
}
+44 -25
View File
@@ -196,9 +196,6 @@ namespace Vocaluxe.Base
CController.Update();
CProfiles.Update();
if (CConfig.CoverLoading == ECoverLoading.TR_CONFIG_COVERLOADING_DYNAMIC && _CurrentScreen != EScreens.ScreenSing)
CSongs.LoadCover();
if (CSettings.ProgramState != EProgramState.EditTheme)
{
run &= _HandleInputs(keys, mouse);
@@ -362,32 +359,55 @@ namespace Vocaluxe.Base
if (!eventsAvailable)
keyEvent = inputKeyEvent;
if (keyEvent.IsArrowKey() || keyEvent.Key == Keys.NumPad0 || keyEvent.Key == Keys.D0)
if (keyEvent.IsArrowKey() || keyEvent.Key == Keys.NumPad0 || keyEvent.Key == Keys.D0 || keyEvent.Key == Keys.Add)
{
_Cursor.Deactivate();
if (keyEvent.ModAlt && keyEvent.ModCtrl && keyEvent.ModShift)
if (keyEvent.ModAlt && keyEvent.ModCtrl)
{
switch (keyEvent.Key)
{
case Keys.Left:
CConfig.BorderLeft -= 1;
CConfig.BorderRight -= 1;
CConfig.BorderTop -= 1;
CConfig.BorderBottom -= 1;
break;
case Keys.Right:
CConfig.BorderLeft += 1;
CConfig.BorderRight += 1;
CConfig.BorderTop += 1;
CConfig.BorderBottom += 1;
if (keyEvent.ModShift)
CConfig.BorderLeft++;
else
CConfig.BorderRight--;
break;
case Keys.Left:
if (keyEvent.ModShift)
CConfig.BorderLeft--;
else
CConfig.BorderRight++;
break;
case Keys.Down:
if (keyEvent.ModShift)
CConfig.BorderTop++;
else
CConfig.BorderBottom--;
break;
case Keys.Up:
if (keyEvent.ModShift)
CConfig.BorderTop--;
else
CConfig.BorderBottom++;
break;
case Keys.D0:
case Keys.NumPad0:
CConfig.BorderLeft = 0;
CConfig.BorderRight = 0;
CConfig.BorderTop = 0;
CConfig.BorderBottom = 0;
CConfig.BorderLeft = CConfig.BorderRight = CConfig.BorderTop = CConfig.BorderBottom = 0;
break;
case Keys.Add:
switch (CConfig.ScreenAlignment)
{
case EGeneralAlignment.Middle:
CConfig.ScreenAlignment = EGeneralAlignment.End;
break;
case EGeneralAlignment.End:
CConfig.ScreenAlignment = EGeneralAlignment.Start;
break;
default:
CConfig.ScreenAlignment = EGeneralAlignment.Middle;
break;
}
break;
}
CConfig.SaveConfig();
@@ -638,16 +658,15 @@ namespace Vocaluxe.Base
}
}
}
CFonts.Style = EStyle.Normal;
CFonts.SetFont("Normal");
CFonts.Height = 25;
CFont font=new CFont("Normal",EStyle.Normal, 25);
SColorF gray = new SColorF(1f, 1f, 1f, 0.5f);
float y = 0;
foreach (string txt in debugOutput)
{
RectangleF rect = new RectangleF(CSettings.RenderW - CFonts.GetTextWidth(txt), y, CFonts.GetTextWidth(txt), CFonts.GetTextHeight(txt));
CDraw.DrawColor(gray, new SRectF(rect.X, rect.Top, rect.Width, rect.Height, CSettings.ZNear));
CFonts.DrawText(txt, rect.X, rect.Y, CSettings.ZNear);
float textWidth = CFonts.GetTextWidth(txt, font);
RectangleF rect = new RectangleF(CSettings.RenderW - textWidth, y, textWidth, CFonts.GetTextHeight(txt,font));
CDraw.DrawRect(gray, new SRectF(rect.X, rect.Top, rect.Width, rect.Height, CSettings.ZNear));
CFonts.DrawText(txt, font, rect.X, rect.Y, CSettings.ZNear);
y += rect.Height;
}
}
+1
View File
@@ -20,6 +20,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using VocaluxeLib;
using VocaluxeLib.Xml;
namespace Vocaluxe.Base
{
+34 -39
View File
@@ -272,12 +272,12 @@ namespace Vocaluxe.Base
return CTheme.GetSkinIndex(partyModeID);
}
public CTexture GetSkinTexture(string textureName, int partyModeID)
public CTextureRef GetSkinTexture(string textureName, int partyModeID)
{
return CTheme.GetSkinTexture(textureName, partyModeID);
}
public CTexture GetSkinVideoTexture(string videoName, int partyModeID)
public CTextureRef GetSkinVideoTexture(string videoName, int partyModeID)
{
return CTheme.GetSkinVideoTexture(videoName, partyModeID);
}
@@ -405,7 +405,7 @@ namespace Vocaluxe.Base
CBackgroundMusic.StopPreview();
}
public CTexture GetVideoTexture()
public CTextureRef GetVideoTexture()
{
return CBackgroundMusic.GetVideoTexture();
}
@@ -413,44 +413,54 @@ namespace Vocaluxe.Base
class CBdraw : IDrawing
{
public void DrawTexture(CTexture texture, SRectF rect)
public void DrawTexture(CTextureRef texture, SRectF rect)
{
CDraw.DrawTexture(texture, rect);
}
public void DrawTexture(CTexture texture, SRectF rect, SColorF color)
public void DrawTexture(CTextureRef texture, SRectF rect, SColorF color)
{
CDraw.DrawTexture(texture, rect, color);
}
public void DrawTexture(CTexture texture, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false)
public void DrawTexture(CTextureRef texture, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false)
{
CDraw.DrawTexture(texture, rect, color, bounds, mirrored);
}
public void DrawTextureReflection(CTexture texture, SRectF rect, SColorF color, SRectF bounds, float reflectionSpace, float reflectionHeight)
public void DrawTexture(CTextureRef textureRef, SRectF bounds, EAspect aspect)
{
CDraw.DrawTextureReflection(texture, rect, color, bounds, reflectionSpace, reflectionHeight);
CDraw.DrawTexture(textureRef, bounds, aspect);
}
public CTexture AddTexture(string fileName)
public void DrawTexture(CTextureRef textureRef, SRectF bounds, EAspect aspect, SColorF color)
{
CDraw.DrawTexture(textureRef, bounds, aspect, color);
}
public void DrawTextureReflection(CTextureRef texture, SRectF rect, SColorF color, float reflectionSpace, float reflectionHeight)
{
CDraw.DrawTextureReflection(texture, rect, color, reflectionSpace, reflectionHeight);
}
public CTextureRef AddTexture(string fileName)
{
return CDraw.AddTexture(fileName);
}
public void RemoveTexture(ref CTexture texture)
public void RemoveTexture(ref CTextureRef texture)
{
CDraw.RemoveTexture(ref texture);
}
public void DrawColor(SColorF color, SRectF rect)
public void DrawRect(SColorF color, SRectF rect)
{
CDraw.DrawColor(color, rect);
CDraw.DrawRect(color, rect);
}
public void DrawColorReflection(SColorF color, SRectF rect, float space, float height)
public void DrawRectReflection(SColorF color, SRectF rect, float space, float height)
{
CDraw.DrawColorReflection(color, rect, space, height);
CDraw.DrawRectReflection(color, rect, space, height);
}
}
@@ -502,39 +512,24 @@ namespace Vocaluxe.Base
class CBfonts : IFonts
{
public void SetFont(string fontName)
{
CFonts.SetFont(fontName);
}
public void SetStyle(EStyle fontStyle)
{
CFonts.Style = fontStyle;
}
public RectangleF GetTextBounds(CText text)
{
return CFonts.GetTextBounds(text);
}
public RectangleF GetTextBounds(CText text, float textHeight)
public void DrawText(string text, CFont font, float x, float y, float z, SColorF color)
{
return CFonts.GetTextBounds(text, textHeight);
CFonts.DrawText(text, font, x, y, z, color);
}
public void DrawText(string text, float textHeight, float x, float y, float z, SColorF color)
public void DrawTextReflection(string text, CFont font, float x, float y, float z, SColorF color, float reflectionSpace, float reflectionHeight)
{
CFonts.DrawText(text, textHeight, x, y, z, color);
CFonts.DrawTextReflection(text, font, x, y, z, color, reflectionSpace, reflectionHeight);
}
public void DrawTextReflection(string text, float textHeight, float x, float y, float z, SColorF color, float reflectionSpace, float reflectionHeight)
public void DrawText(string text, CFont font, float x, float y, float z, SColorF color, float begin, float end)
{
CFonts.DrawTextReflection(text, textHeight, x, y, z, color, reflectionSpace, reflectionHeight);
}
public void DrawText(string text, float textHeight, float x, float y, float z, SColorF color, float begin, float end)
{
CFonts.DrawText(text, textHeight, x, y, z, color, begin, end);
CFonts.DrawText(text, font, x, y, z, color, begin, end);
}
}
@@ -656,7 +651,7 @@ namespace Vocaluxe.Base
return CProfiles.GetPlayerName(profileID, playerNum);
}
public CTexture GetAvatar(int profileID)
public CTextureRef GetAvatar(int profileID)
{
return CProfiles.GetAvatarTextureFromProfile(profileID);
}
@@ -815,7 +810,7 @@ namespace Vocaluxe.Base
return CVideo.Skip(videoStream, startPosition, videoGap);
}
public bool GetFrame(int videoStream, ref CTexture videoTexture, float time, out float videoTime)
public bool GetFrame(int videoStream, ref CTextureRef videoTexture, float time, out float videoTime)
{
return CVideo.GetFrame(videoStream, ref videoTexture, time, out videoTime);
}
@@ -896,7 +891,7 @@ namespace Vocaluxe.Base
class CBcover : ICover
{
public CTexture GetNoCover()
public CTextureRef GetNoCover()
{
return CCover.NoCover;
}
@@ -904,7 +899,7 @@ namespace Vocaluxe.Base
class CBdataBase : IDataBase
{
public bool GetCover(string fileName, ref CTexture texture, int coverSize)
public bool GetCover(string fileName, ref CTextureRef texture, int coverSize)
{
return CDataBase.GetCover(fileName, ref texture, coverSize);
}
+495
View File
@@ -0,0 +1,495 @@
#region license
// This file is part of Vocaluxe.
//
// Vocaluxe 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 3 of the License, or
// (at your option) any later version.
//
// Vocaluxe 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 Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
#endregion
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.IO;
using Vocaluxe.Base.Fonts;
using VocaluxeLib;
using System.Linq;
namespace Vocaluxe.Base
{
/// <summary>
/// Class that generates Covers if the right Cover is missing
/// Themeable via the xml of the Cover theme
/// </summary>
class CNoCoverGenerator
{
private readonly bool _Valid;
private readonly SThemeCoverGenerator _Theme;
private readonly string _Image;
private readonly SColorF _TextColor;
private readonly SColorF _BGColor;
private const int _LineSpace = 5;
/// <summary>
/// Split lines after special chars, descending priority
/// </summary>
private static readonly char[] _SplitCharPreferences = {':', '/', '-'};
private static readonly char[] _SplitCharAfter = {':', '/', '-', ' ', ')', '.', '*', ','};
private static readonly char[] _SplitCharBefore = {'('};
public CNoCoverGenerator(SThemeCoverGenerator theme, string basePath)
{
_Theme = theme;
_Valid = true;
_Valid &= _Theme.Text.Color.Get(-1, out _TextColor);
_Valid &= _Theme.BackgroundColor.Get(-1, out _BGColor);
if (_Valid)
{
_Image = Path.Combine(basePath, _Theme.Image);
_Valid = File.Exists(_Image);
}
}
private class CTextElement
{
public readonly string Text;
public float Width, Height;
private readonly Graphics _Graphics;
private readonly Font _Font;
private float _WidthTrimmed = -1;
public float WidthTrimmed
{
get
{
if (_WidthTrimmed < 0f)
{
string text = Text.TrimEnd(null);
_WidthTrimmed = text.Length == Text.Length ? Width : _Graphics.MeasureString(text, _Font, -1, StringFormat.GenericTypographic).Width;
}
return _WidthTrimmed;
}
}
public int Line;
public CTextElement(string text, Graphics g, Font font)
{
Text = text;
SizeF dimensions = g.MeasureString(text, font, -1, StringFormat.GenericTypographic);
Width = dimensions.Width;
Height = (dimensions.Height + font.Height) / 2;
_Graphics = g;
_Font = font;
}
public void AdjustSize(float factor)
{
Width *= factor;
_WidthTrimmed *= factor;
Height *= factor;
}
}
private void _DrawBackground(Graphics g, Bitmap bmpBackground, String firstCoverPath)
{
g.Clear(_BGColor.AsColor());
ImageAttributes ia = null;
if (_Theme.ShowFirstCover && !String.IsNullOrEmpty(firstCoverPath) && File.Exists(firstCoverPath))
{
using (Bitmap bmp2 = new Bitmap(firstCoverPath))
g.DrawImage(bmp2, bmpBackground.GetRect(), 0, 0, bmp2.Width, bmp2.Height, GraphicsUnit.Pixel);
ColorMatrix cm = new ColorMatrix {Matrix33 = _Theme.ImageAlpha};
ia = new ImageAttributes();
ia.SetColorMatrix(cm);
}
g.DrawImage(bmpBackground, bmpBackground.GetRect(), 0, 0, bmpBackground.Width, bmpBackground.Height, GraphicsUnit.Pixel, ia);
}
private void _DrawText(Graphics g, Size bmpSize, CFont font, List<CTextElement> elements)
{
Font fo = CFonts.GetSystemFont(font);
float maxHeight = elements.Select(el => el.Height).Max();
int lineCount = elements.Last().Line + 1;
//Have to use size in em not pixels!
float emSize = fo.Size * fo.FontFamily.GetCellAscent(fo.Style) / fo.FontFamily.GetEmHeight(fo.Style);
float outlineSize = CFonts.GetOutlineSize(font) * font.Height;
SColorF outlineColorF = CFonts.GetOutlineColor(font);
outlineColorF.A = outlineColorF.A * _TextColor.A;
using (var path = new GraphicsPath())
using (var pen = new Pen(outlineColorF.AsColor(), outlineSize / 2))
{
pen.LineJoin = LineJoin.Round;
pen.Alignment = PenAlignment.Outset;
float top = (bmpSize.Height - _Theme.Text.Margin.Bottom - _Theme.Text.Margin.Top - maxHeight * lineCount) / 2 + _Theme.Text.Margin.Top;
int nextLineEl = 0;
for (int i = 0; i < lineCount; i++)
{
int firstEl = nextLineEl;
for (; nextLineEl < elements.Count; nextLineEl++)
{
if (elements[nextLineEl].Line > i)
break;
}
string line = elements.GetRange(firstEl, nextLineEl - firstEl).Aggregate("", (current, element) => current + element.Text);
float left;
if (lineCount == 1 || (i == 1 && lineCount == 3))
{
//Center Text if this is the only line or the middle line
float width = _GetWidth(elements, firstEl, nextLineEl - 1);
left = (bmpSize.Width - _Theme.Text.Margin.Left - _Theme.Text.Margin.Right - width) / 2 + _Theme.Text.Margin.Left;
}
else if (i == lineCount - 1)
{
//Place last line at right
float width = _GetWidth(elements, firstEl, nextLineEl - 1);
left = bmpSize.Width - width - _Theme.Text.Margin.Right;
}
else
left = _Theme.Text.Margin.Left;
//g.DrawString(line, fo, new SolidBrush(_TextColor.AsColor()), left, top, StringFormat.GenericTypographic);
path.AddString(line, fo.FontFamily, (int)fo.Style, emSize, new PointF(left, top), StringFormat.GenericTypographic);
top += maxHeight + _LineSpace;
}
g.DrawPath(pen, path);
g.FillPath(new SolidBrush(_TextColor.AsColor()), path);
}
}
public Bitmap GetCover(string text, string firstCoverPath)
{
if (!_Valid)
return null;
text = CLanguage.Translate(_Theme.Text.Text.Replace("%TEXT%", text));
using (Bitmap bmpImage = new Bitmap(_Image))
{
Bitmap bmp = new Bitmap(bmpImage.Width, bmpImage.Height, PixelFormat.Format32bppArgb);
try
{
using (Graphics g = Graphics.FromImage(bmp))
{
g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.TextRenderingHint = TextRenderingHint.AntiAlias;
_DrawBackground(g, bmpImage, firstCoverPath);
if (text != "")
{
CFont font = new CFont(_Theme.Text.Font);
Font fo = CFonts.GetSystemFont(font);
IEnumerable<string> textParts = _SplitText(text);
List<CTextElement> elements = textParts.Select(line => new CTextElement(line, g, fo)).ToList();
float factor = _DistributeText(elements, bmp.Width, bmp.Height);
foreach (CTextElement element in elements)
element.AdjustSize(factor);
font.Height *= factor / (1f + CFonts.GetOutlineSize(font)); //Adjust for outline size
_DrawText(g, bmp.GetSize(), font, elements);
}
}
return bmp;
}
catch (Exception)
{
bmp.Dispose();
}
}
return null;
}
/// <summary>
/// Distributes the text among max. 3 lines maximizing the height of the line<br />
/// Sets the Line field in the elements
/// </summary>
/// <param name="elements">Text with set Width and Height</param>
/// <param name="width">Image Width</param>
/// <param name="height">Image Height</param>
/// <returns>Factor for resizing the text (Maximizing this factor means maximizing the height)</returns>
private float _DistributeText(List<CTextElement> elements, int width, int height)
{
int availableWidth = width - _Theme.Text.Margin.Left - _Theme.Text.Margin.Right;
int availableHeight = height - _Theme.Text.Margin.Top - _Theme.Text.Margin.Bottom;
float textHeight = elements.Select(el => el.Height).Max();
//Try 1 line:
float textWidth = _GetWidth(elements, 0);
int maxHeight = Math.Min(availableHeight, (int)_Theme.Text.Font.Size);
float factorH = maxHeight / textHeight;
float factorW = availableWidth / textWidth;
if (factorH <= factorW)
return factorH; //Limited by Height
float factor1 = factorW;
//Try 2 lines
if (elements.Count == 1)
{
//Only 1 element -> 1 line
return factor1;
}
availableWidth -= _Theme.Text.Indent;
maxHeight = Math.Min(availableHeight / 2 - _LineSpace, (int)_Theme.Text.Font.Size);
factorH = maxHeight / textHeight;
if (factorH <= factor1)
return factor1; //Cannot get any bigger with more lines
int splitEl = _GetSplitElement(elements, textWidth / 2);
Debug.Assert(splitEl >= 0 && splitEl < elements.Count - 1);
float width1 = _GetWidth(elements, 0, splitEl);
float width2 = _GetWidth(elements, splitEl + 1);
factorW = availableWidth / Math.Max(width1, width2);
if (factorH <= factorW)
{
// Assertion: factorH>factor1 (check above) && factorH<=factorW --> Min(factorH,factorW)>factor 1
// but for 2 lines it is limited by height
// --> Use 2 lines
_SetLine(elements, splitEl + 1, elements.Count - 1, 1);
return factorH;
}
// factor2 < factorH && factorH>factor1
float factor2 = factorW;
//Try 3 lines
maxHeight = Math.Min(availableHeight / 3 - 2 * _LineSpace, (int)_Theme.Text.Font.Size);
factorH = maxHeight / textHeight;
if (elements.Count == 2 || factorH <= Math.Max(factor1, factor2))
{
//Only 2 elements or cannot get any bigger
if (factor2 <= factor1)
return factor1;
_SetLine(elements, splitEl + 1, elements.Count - 1, 1);
return factor2;
}
int splitEl21 = _GetSplitElement(elements, textWidth / 3, false);
int splitEl22 = _GetSplitElement(elements, textWidth / 3, true, splitEl21 + 1);
Debug.Assert(splitEl21 >= 0 && splitEl21 < splitEl22 && splitEl22 < elements.Count - 1);
float width21 = _GetWidth(elements, 0, splitEl21);
float width22 = _GetWidth(elements, splitEl21 + 1, splitEl22);
float width23 = _GetWidth(elements, splitEl22 + 1);
factorW = availableWidth / Math.Max(Math.Max(width21, width22), width23);
float factor3 = Math.Min(factorH, factorW);
if (factor3 > Math.Max(factor1, factor2))
{
_SetLine(elements, splitEl21 + 1, splitEl22, 1);
_SetLine(elements, splitEl22 + 1, elements.Count - 1, 2);
return factor3;
}
if (factor2 > factor1)
{
_SetLine(elements, splitEl + 1, elements.Count - 1, 1);
return factor2;
}
return factor1;
}
/// <summary>
/// Returns the width of the elements with index from start to end of the list (inclusive) if they are put on 1 line
/// </summary>
/// <param name="list"></param>
/// <param name="start"></param>
/// <returns></returns>
private static float _GetWidth(List<CTextElement> list, int start)
{
return _GetWidth(list, start, list.Count - 1);
}
/// <summary>
/// Returns the width of the elements with index from start to end (inclusive) if they are put on 1 line
/// </summary>
/// <param name="list"></param>
/// <param name="start"></param>
/// <param name="end"></param>
/// <returns></returns>
private static float _GetWidth(List<CTextElement> list, int start, int end)
{
if (start < 0)
start = 0;
if (end >= list.Count)
end = list.Count - 1;
if (start > end)
return 0f;
float width = list.GetRange(start, end - start).Select(el => el.Width).Sum();
return width + list[end].WidthTrimmed;
}
private static void _SetLine(List<CTextElement> list, int start, int end, int line)
{
for (int i = start; i <= end; i++)
list[i].Line = line;
}
/// <summary>
/// Find the element after which to split the line
/// </summary>
/// <param name="elements">List with elements, width must be set</param>
/// <param name="requestedWidth">The requested line width</param>
/// <param name="singleSplit">Split on one point or two</param>
/// <param name="startElement">First element on line</param>
/// <returns>Index of element AFTER which to split</returns>
private static int _GetSplitElement(List<CTextElement> elements, float requestedWidth, bool singleSplit = true, int startElement = 0)
{
//Assert we have enough elements
Debug.Assert(singleSplit && elements.Count - startElement >= 2 || !singleSplit && elements.Count - startElement >= 3);
float curWidth = 0f;
int splitEl;
for (splitEl = startElement; splitEl < elements.Count; splitEl++)
{
curWidth += elements[splitEl].Width;
if (curWidth >= requestedWidth)
break;
}
// At this point we can either keep splitEl on this line for move it to the next line
// ==> line with splitEl is to long, without it is to short. so find the best option
// Check if line starts or ends with a long word, than put that on a single line
if (splitEl == startElement)
return splitEl;
// These 2 conditions also cover if the text fits on 1 line
if (!singleSplit && splitEl >= elements.Count - 2)
return elements.Count - 3; // Make sure we have 2 elements left if in multi split mode!
if (splitEl >= elements.Count - 1)
return elements.Count - 2; // Make sure we have 1 element left!
float diffWith = curWidth - requestedWidth;
float diffWithout = requestedWidth - (curWidth - elements[splitEl].Width);
if (!singleSplit)
{
// If we split in 3 lines, add the error of the next 2 lines to the current error for both cases
int splitEl2 = _GetSplitElement(elements, requestedWidth, true, splitEl + 1);
int splitEl3 = _GetSplitElement(elements, requestedWidth, true, splitEl);
diffWith += Math.Abs(requestedWidth - _GetWidth(elements, splitEl + 1, splitEl2)) + Math.Abs(requestedWidth - _GetWidth(elements, splitEl2 + 1));
diffWithout += Math.Abs(requestedWidth - _GetWidth(elements, splitEl, splitEl3)) + Math.Abs(requestedWidth - _GetWidth(elements, splitEl3 + 1));
}
float diff = diffWith - diffWithout;
//Differences below this value are considered acceptable
float equalDist = requestedWidth * 0.025f;
if (diff > equalDist)
return splitEl - 1; // width error with element is much higher than without -> put element on next line
if (diff < -equalDist)
return splitEl; // width error with element is much less than without -> keep element on line
//The real split would be somewhere in the middle of the element so we can move it to either line
string tmp = elements[splitEl].Text.TrimEnd(null);
char lastCharWith = tmp[tmp.Length - 1];
tmp = elements[splitEl - 1].Text.TrimEnd(null);
char lastCharWithout = tmp[tmp.Length - 1];
//Check if last chars are special chars
if (Char.IsLetterOrDigit(lastCharWith))
{
if (Char.IsLetterOrDigit(lastCharWithout))
return startElement == 0 ? splitEl : splitEl - 1; //Both are alphanumeric, favor longer first lines but shorter middle lines
return splitEl - 1; //Split after non-alphanumeric char
}
if (Char.IsLetterOrDigit(lastCharWithout))
return splitEl; //Split after non-alphanumeric char
int indexWith = Array.IndexOf(_SplitCharPreferences, lastCharWith);
int indexWithout = Array.IndexOf(_SplitCharPreferences, lastCharWithout);
if (indexWith <= indexWithout)
return startElement == 0 ? splitEl : splitEl - 1; //favor longer first lines but shorter middle lines
return splitEl - 1;
}
/// <summary>
/// Split the text in parts that can then be distributet among the lines
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
private static IEnumerable<string> _SplitText(string text)
{
Debug.Assert(!String.IsNullOrWhiteSpace(text));
text = text.Trim().TrimMultipleWs();
List<string> lines = new List<string>();
if (text.Length == 1)
{
lines.Add(text);
return lines;
}
//Split the text on non-letter chars
int curStart = 0;
for (int i = 1; i < text.Length - 1; i++)
{
if ((Array.IndexOf(_SplitCharAfter, text[i]) >= 0 && (Char.IsLetterOrDigit(text, i + 1) || Array.IndexOf(_SplitCharBefore, text[i + 1]) >= 0)) ||
(Char.IsLetterOrDigit(text, i) && Array.IndexOf(_SplitCharBefore, text[i + 1]) >= 0))
{
lines.Add(text.Substring(curStart, i - curStart + 1));
curStart = ++i;
}
}
//Add the rest
lines.Add(text.Substring(curStart));
//Check for initials (like J. R.R. Tolkien) and join them
curStart = -1;
string curText = "";
for (int i = 0; i < lines.Count; i++)
{
string part = lines[i].Trim();
if (part.Length == 2 && part[1] == '.')
{
//Initials found, continue or start new
if (curStart < 0)
curStart = i;
curText += lines[i];
}
else if (curStart >= 0)
{
//Initials end
if (curStart < i - 1)
{
//More than 1 part
lines[curStart] = curText;
lines.RemoveRange(curStart + 1, i - curStart - 1);
i = curStart;
}
curText = "";
curStart = -1;
}
}
//Handle last part
if (curStart >= 0)
{
//Initials end
if (curStart < lines.Count - 1)
{
//More than 1 part
lines[curStart] = curText;
lines.RemoveRange(curStart + 1, lines.Count - curStart - 1);
}
}
// Remove single char lines
for (int i = 0; i < lines.Count; i++)
{
string part = lines[i];
if (part.Trim().Length == 1)
{
lines.RemoveAt(i);
if (i == 0)
lines[0] = part + lines[0];
else
{
lines[i - 1] += part;
i--;
}
}
}
return lines;
}
}
}
+1 -1
View File
@@ -23,6 +23,7 @@ using System.Reflection;
using VocaluxeLib;
using VocaluxeLib.Menu;
using VocaluxeLib.PartyModes;
using VocaluxeLib.Xml;
namespace Vocaluxe.Base
{
@@ -99,7 +100,6 @@ namespace Vocaluxe.Base
pair.Value.PartyMode.SaveScreens();
}
public static List<SPartyModeInfos> GetPartyModeInfos()
{
var infos = new List<SPartyModeInfos>();
+1 -1
View File
@@ -61,7 +61,7 @@ namespace Vocaluxe.Base
get { return _Song != null ? _Song.Finish : 0f; }
}
public CTexture Cover
public CTextureRef Cover
{
get { return _Song != null ? _Song.CoverTextureSmall : CCover.NoCover; }
}
+2 -2
View File
@@ -504,7 +504,7 @@ namespace Vocaluxe.Base
#endregion profile properties
#region avatar texture
public static CTexture GetAvatarTexture(int avatarID)
public static CTextureRef GetAvatarTexture(int avatarID)
{
if (!IsAvatarIDValid(avatarID))
return null;
@@ -512,7 +512,7 @@ namespace Vocaluxe.Base
return _Avatars[avatarID].Texture;
}
public static CTexture GetAvatarTextureFromProfile(int profileID)
public static CTextureRef GetAvatarTextureFromProfile(int profileID)
{
if (!IsProfileIDValid(profileID) || _Profiles[profileID].Avatar == null)
return null;
+4
View File
@@ -178,7 +178,11 @@ namespace Vocaluxe.Base
}
foreach (CCategory cat in _Categories)
{
cat.CoverTextureSmall = CCover.Cover(cat.Name);
if (cat.CoverTextureSmall == CCover.NoCover)
cat.CoverTextureSmall = CCover.GenerateCover(cat.Name, CSongs.Sorter.SongSorting, cat);
}
_Changed = false;
}
}
+30 -48
View File
@@ -21,6 +21,7 @@ using System.Collections.ObjectModel;
using System.Linq;
using System.Threading;
using System.IO;
using System.Threading.Tasks;
using VocaluxeLib;
using VocaluxeLib.Songs;
@@ -134,23 +135,13 @@ namespace Vocaluxe.Base
Category--;
}
public static int GetNextSongWithoutCover(ref CSong song)
private static int _NumSongsWithCoverLoaded;
public static int NumSongsWithCoverLoaded
{
if (!SongsLoaded)
return -1;
if (NumSongsWithCoverLoaded < _Songs.Count)
{
song = _Songs[NumSongsWithCoverLoaded];
NumSongsWithCoverLoaded++;
return NumSongsWithCoverLoaded;
}
return -2;
get { return _NumSongsWithCoverLoaded; }
private set { _NumSongsWithCoverLoaded = value; }
}
public static int NumSongsWithCoverLoaded { get; private set; }
public static string GetCurrentCategoryName()
{
return _IsCatIndexValid(_CatIndex) ? Categories[_CatIndex].Name : "";
@@ -371,59 +362,50 @@ namespace Vocaluxe.Base
Category = -1;
SongsLoaded = true;
if (CConfig.CoverLoading == ECoverLoading.TR_CONFIG_COVERLOADING_ATSTART)
switch (CConfig.CoverLoading)
{
CLog.StartBenchmark("Load Covers/Notes");
_LoadCover();
CLog.StopBenchmark("Load Covers/Notes");
case ECoverLoading.TR_CONFIG_COVERLOADING_ATSTART:
_LoadCovers();
break;
case ECoverLoading.TR_CONFIG_COVERLOADING_DYNAMIC:
_LoadCoversAsync();
break;
}
CLog.StopBenchmark("Load Songs ");
CLog.StopBenchmark("Load Songs");
}
public static void LoadCover()
private static void _LoadCoversAsync()
{
if (CConfig.Renderer == ERenderer.TR_CONFIG_SOFTWARE)
return; //should be removed as soon as the other renderer are ready for queue
if (!SongsLoaded || CoverLoaded)
return;
if (_CoverLoaderThread != null)
return;
_CoverLoaderThread = new Thread(_LoadCover) {Name = "CoverLoader", Priority = ThreadPriority.BelowNormal, IsBackground = true};
_CoverLoaderThread = new Thread(_LoadCovers) {Name = "CoverLoader", Priority = ThreadPriority.BelowNormal, IsBackground = true};
_CoverLoaderThread.Start();
/*
if (_CoverLoadTimer.ElapsedMilliseconds >= WaitTime)
{
for (int i = 0; i < NumLoads; i++)
{
CSong song = null;
int n = GetNextSongWithoutCover(ref song);
if (n < 0)
return;
song.LoadSmallCover();
if (n == NumAllSongs)
CDataBase.CommitCovers();
}
_CoverLoadTimer.Reset();
_CoverLoadTimer.Start();
}
* */
}
private static void _LoadCover()
private static void _LoadCovers()
{
CLog.StartBenchmark("Load Covers");
int songCount = _Songs.Count;
AutoResetEvent ev = new AutoResetEvent(songCount == 0);
NumSongsWithCoverLoaded = 0;
foreach (CSong song in _Songs)
{
song.LoadSmallCover();
NumSongsWithCoverLoaded++;
CSong tmp = song;
Task.Factory.StartNew(() =>
{
tmp.LoadSmallCover();
if (Interlocked.Increment(ref _NumSongsWithCoverLoaded) >= songCount)
ev.Set();
});
}
ev.WaitOne();
_CoverLoaded = true;
CDataBase.CommitCovers();
CLog.StopBenchmark("Load Covers");
}
}
}
+5 -4
View File
@@ -23,6 +23,7 @@ using System.Xml;
using Vocaluxe.Base.Fonts;
using VocaluxeLib;
using VocaluxeLib.Draw;
using VocaluxeLib.Xml;
namespace Vocaluxe.Base
{
@@ -44,7 +45,7 @@ namespace Vocaluxe.Base
class CSkinElement
{
public string Value;
public CTexture Texture;
public CTextureRef Texture;
}
class CVideoSkinElement : CSkinElement
@@ -266,7 +267,7 @@ namespace Vocaluxe.Base
{
CFonts.LoadThemeFonts(
_Themes[themeIndex].Name,
Path.Combine(Path.Combine(_Themes[themeIndex].Path, _Themes[themeIndex].SkinFolder), CSettings.FolderNameThemeFonts),
Path.Combine(_Themes[themeIndex].Path, _Themes[themeIndex].SkinFolder, CSettings.FolderNameThemeFonts),
xmlReader);
}
else
@@ -554,7 +555,7 @@ namespace Vocaluxe.Base
return path;
}
public static CTexture GetSkinTexture(string textureName, int partyModeID)
public static CTextureRef GetSkinTexture(string textureName, int partyModeID)
{
int skinIndex = GetSkinIndex(partyModeID);
CSkinElement sk;
@@ -597,7 +598,7 @@ namespace Vocaluxe.Base
return null;
}
public static CTexture GetSkinVideoTexture(string videoName, int partyModeID)
public static CTextureRef GetSkinVideoTexture(string videoName, int partyModeID)
{
CVideoSkinElement sk = GetSkinVideo(videoName, partyModeID);
if (sk == null)
+1 -1
View File
@@ -75,7 +75,7 @@ namespace Vocaluxe.Base
return _VideoDecoder.GetLength(streamID);
}
public static bool GetFrame(int streamID, ref CTexture frame, float time, out float videoTime)
public static bool GetFrame(int streamID, ref CTextureRef frame, float time, out float videoTime)
{
return _VideoDecoder.GetFrame(streamID, ref frame, time, out videoTime);
}
+2 -5
View File
@@ -7,7 +7,7 @@ namespace Vocaluxe.Base
{
class CVideoPlayer
{
private CTexture _VideoTexture;
private CTextureRef _VideoTexture;
private int _VideoStream;
private readonly Stopwatch _VideoTimer = new Stopwatch();
private bool _Finished;
@@ -62,11 +62,8 @@ namespace Vocaluxe.Base
}
if (_VideoTexture == null)
return;
var bounds = new RectangleF(0f, 0f, CSettings.RenderW, CSettings.RenderH);
RectangleF rect;
CHelper.SetRect(bounds, out rect, _VideoTexture.OrigAspect, EAspect.Crop);
CDraw.DrawTexture(_VideoTexture, new SRectF(rect.X, rect.Y, rect.Width, rect.Height, CSettings.ZFar / 4));
CDraw.DrawTexture(_VideoTexture, new SRectF(0, 0, CSettings.RenderW, CSettings.RenderH, CSettings.ZFar / 4), EAspect.Crop);
}
public void PreLoad()
+1 -1
View File
@@ -57,7 +57,7 @@ namespace Vocaluxe.Base
_Webcam = null;
}
public static bool GetFrame(ref CTexture tex)
public static bool GetFrame(ref CTextureRef tex)
{
return _Webcam != null && _Webcam.GetFrame(ref tex);
}
@@ -24,48 +24,64 @@ using VocaluxeLib.Draw;
namespace Vocaluxe.Base.Fonts
{
class CFont : IDisposable
class CFontStyle : IDisposable
{
private readonly Dictionary<char, CGlyph> _Glyphs;
private readonly string _FilePath;
private readonly EStyle _Style;
public readonly float Outline; //0..1, 0=not outline 1=100% outline
public readonly SColorF OutlineColor;
private readonly float _MaxGlyphHeight;
private readonly Dictionary<char, CGlyph> _Glyphs = new Dictionary<char, CGlyph>();
private PrivateFontCollection _Fonts;
private FontFamily _Family;
private readonly float _MaxGlyphHeight;
private readonly string _FilePath;
private bool _Disposed;
public CFont(string file)
public CFontStyle(string file, EStyle style, float outline, SColorF outlineColor)
{
_FilePath = file;
_Glyphs = new Dictionary<char, CGlyph>();
_Style = style;
Outline = outline;
OutlineColor = outlineColor;
switch (CConfig.TextureQuality)
{
case ETextureQuality.TR_CONFIG_TEXTURE_LOWEST:
_MaxGlyphHeight = 25f;
_MaxGlyphHeight = 20f;
break;
case ETextureQuality.TR_CONFIG_TEXTURE_LOW:
_MaxGlyphHeight = 50f;
_MaxGlyphHeight = 40f;
break;
case ETextureQuality.TR_CONFIG_TEXTURE_MEDIUM:
_MaxGlyphHeight = 100f;
_MaxGlyphHeight = 60f;
break;
case ETextureQuality.TR_CONFIG_TEXTURE_HIGH:
_MaxGlyphHeight = 200f;
_MaxGlyphHeight = 80f;
break;
case ETextureQuality.TR_CONFIG_TEXTURE_HIGHEST:
_MaxGlyphHeight = 400f;
break;
default:
_MaxGlyphHeight = 100f;
break;
default:
_MaxGlyphHeight = 60f;
break;
}
_MaxGlyphHeight = 50;
}
public Font GetFont()
private FontStyle _GetSystemFontStyle()
{
switch (_Style)
{
case EStyle.Normal:
return FontStyle.Regular;
case EStyle.Italic:
return FontStyle.Italic;
case EStyle.Bold:
return FontStyle.Bold;
case EStyle.BoldItalic:
return FontStyle.Bold | FontStyle.Italic;
}
throw new ArgumentException("Invalid style: " + _Style);
}
public Font GetSystemFont(float height)
{
if (_Fonts == null)
{
@@ -80,100 +96,83 @@ namespace Vocaluxe.Base.Fonts
CLog.LogError("Error opening font file " + _FilePath + ": " + e.Message);
}
}
return new Font(_Family, CFonts.Height, CFonts.GetFontStyle(), GraphicsUnit.Pixel);
return new Font(_Family, height, _GetSystemFontStyle(), GraphicsUnit.Pixel);
}
public void DrawGlyph(char chr, float x, float y, float z, SColorF color)
public void DrawGlyph(char chr, float fontHeight, float x, float y, float z, SColorF color)
{
CTexture texture;
CTextureRef texture;
SRectF rect;
GetOrAddGlyph(chr).GetTextureAndRect(x, y, z, out texture, out rect);
GetOrAddGlyph(chr, fontHeight).GetTextureAndRect(fontHeight, x, y, z, out texture, out rect);
CDraw.DrawTexture(texture, rect, color);
}
public void DrawGlyph(char chr, float x, float y, float z, SColorF color, float begin, float end)
public void DrawGlyph(char chr, float fontHeight, float x, float y, float z, SColorF color, float begin, float end)
{
CTexture texture;
CTextureRef texture;
SRectF rect;
GetOrAddGlyph(chr).GetTextureAndRect(x, y, z, out texture, out rect);
GetOrAddGlyph(chr, fontHeight).GetTextureAndRect(fontHeight, x, y, z, out texture, out rect);
CDraw.DrawTexture(texture, rect, color, begin, end);
}
public void DrawGlyphReflection(char chr, float x, float y, float z, SColorF color, float rspace, float rheight)
public void DrawGlyphReflection(char chr, float fontHeight, float x, float y, float z, SColorF color, float rspace, float rheight)
{
CTexture texture;
CTextureRef texture;
SRectF rect;
GetOrAddGlyph(chr).GetTextureAndRect(x, y, z, out texture, out rect);
CDraw.DrawTextureReflection(texture, rect, color, rect, rspace, rheight);
GetOrAddGlyph(chr, fontHeight).GetTextureAndRect(fontHeight, x, y, z, out texture, out rect);
CDraw.DrawTextureReflection(texture, rect, color, rspace, rheight);
}
public float GetWidth(char chr)
public float GetWidth(char chr, float height)
{
return GetOrAddGlyph(chr).Width;
return GetOrAddGlyph(chr, height).GetWidth(height);
}
public float GetHeight(char chr)
public float GetHeight(char chr, float height)
{
return GetOrAddGlyph(chr).Height;
return GetOrAddGlyph(chr, height).GetHeight(height);
}
public CGlyph GetOrAddGlyph(char chr)
public CGlyph GetOrAddGlyph(char chr, float height)
{
CGlyph glyph;
if (!_Glyphs.TryGetValue(chr, out glyph))
{
glyph = new CGlyph(chr, _MaxGlyphHeight);
float maxHeight = (height < 0 || _MaxGlyphHeight + 50 >= height) ? _MaxGlyphHeight : (float)Math.Round(height / 50) * 50;
glyph = new CGlyph(chr, this, maxHeight);
_Glyphs.Add(chr, glyph);
}
if (glyph.MaxHeight + 50 < CFonts.Height)
if (glyph.MaxHeight + 50 < height)
{
glyph.UnloadTexture();
glyph = new CGlyph(chr, (float)Math.Round(CFonts.Height / 50) * 50);
glyph = new CGlyph(chr, this, (float)Math.Round(height / 50) * 50);
_Glyphs[chr] = glyph;
}
return glyph;
}
public void UnloadGlyphs()
private void _UnloadGlyphs()
{
foreach (CGlyph glyph in _Glyphs.Values)
glyph.UnloadTexture();
_Glyphs.Clear();
}
private bool _Disposed;
public void Dispose()
{
if (!_Disposed)
{
if (_Fonts != null)
{
_Fonts.Dispose();
UnloadGlyphs();
_Fonts = null;
}
_UnloadGlyphs();
_Disposed = true;
}
GC.SuppressFinalize(this);
}
}
struct SFont
{
public string Name;
public bool IsThemeFont;
public int PartyModeID;
public string ThemeName;
public string Folder;
public string FileNormal;
public string FileItalic;
public string FileBold;
public string FileBoldItalic;
public float Outline; //0..1, 0=not outline 1=100% outline
public SColorF OutlineColor;
public CFont Normal;
public CFont Italic;
public CFont Bold;
public CFont BoldItalic;
}
}
+259 -321
View File
@@ -15,216 +15,166 @@
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
#endregion
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Xml;
using VocaluxeLib;
using VocaluxeLib.Menu;
using VocaluxeLib.Xml;
namespace Vocaluxe.Base.Fonts
{
/// <summary>
/// Struct used for describing a font family (a type of text with 4 different styles)
/// </summary>
struct SFontFamily
{
public string Name;
public int PartyModeID;
public string ThemeName;
public string Folder;
public string FileNormal;
public string FileItalic;
public string FileBold;
public string FileBoldItalic;
public float Outline; //0..1, 0=not outline 1=100% outline
public SColorF OutlineColor;
public CFontStyle Normal;
public CFontStyle Italic;
public CFontStyle Bold;
public CFontStyle BoldItalic;
public void Dispose()
{
Normal.Dispose();
Italic.Dispose();
Bold.Dispose();
BoldItalic.Dispose();
}
}
static class CFonts
{
private static readonly List<SFont> _Fonts = new List<SFont>();
private static int _CurrentFont;
private static float _Height = 1f;
private static bool _IsInitialized;
private static readonly List<SFontFamily> _FontFamilies = new List<SFontFamily>();
private static readonly List<String> _LoggedMissingFonts = new List<string>();
// ReSharper disable MemberCanBePrivate.Global
public static int PartyModeID { get; set; }
// ReSharper restore MemberCanBePrivate.Global
public static EStyle Style = EStyle.Normal;
public static float Height
public static bool Init()
{
get { return _Height; }
set { _Height = value < 0f ? 0f : value; }
}
public static float Outline
{
get { return _Fonts[_CurrentFont].Outline; }
}
public static SColorF OutlineColor
{
get { return _Fonts[_CurrentFont].OutlineColor; }
}
public static void Init()
{
_CurrentFont = 0;
if (_IsInitialized)
return false;
PartyModeID = -1;
_BuildFonts();
return _LoadDefaultFonts();
}
private static void _BuildFonts()
public static void Close()
{
foreach (SFont font in _Fonts)
{
font.Normal.Dispose();
font.Bold.Dispose();
font.Italic.Dispose();
font.BoldItalic.Dispose();
}
_Fonts.Clear();
_CurrentFont = 0;
_LoadFontList();
}
public static Font GetFont()
{
return _GetCurrentFont().GetFont();
}
private static CFont _GetCurrentFont()
{
switch (Style)
{
case EStyle.Normal:
return _Fonts[_CurrentFont].Normal;
case EStyle.Italic:
return _Fonts[_CurrentFont].Italic;
case EStyle.Bold:
return _Fonts[_CurrentFont].Bold;
case EStyle.BoldItalic:
return _Fonts[_CurrentFont].BoldItalic;
}
//Just in case...
return _Fonts[_CurrentFont].Normal;
foreach (SFontFamily font in _FontFamilies)
font.Dispose();
_FontFamilies.Clear();
_IsInitialized = false;
}
#region DrawText
public static void DrawText(string text, int x, int y, int h)
/// <summary>
/// Draws a black text
/// </summary>
/// <param name="text">The text to be drawn</param>
/// <param name="font">The texts font</param>
/// <param name="x">The texts x-position</param>
/// <param name="y">The texts y-position</param>
/// <param name="z">The texts z-position</param>
public static void DrawText(string text, CFont font, float x, float y, float z)
{
DrawText(text, h, x, y, 0f, new SColorF(0f, 0f, 0f, 1f));
}
public static void DrawText(string text, float x, float y, float z)
{
DrawText(text, Height, x, y, z, new SColorF(0f, 0f, 0f, 1f));
DrawText(text, font, x, y, z, new SColorF(0f, 0f, 0f, 1f));
}
/// <summary>
/// Draws a text string
/// Draws a text
/// </summary>
/// <param name="text">The text to be drawn</param>
/// <param name="x">The text's x-position</param>
/// <param name="y">The text's y-position</param>
/// <param name="h">The text's height</param>
/// <param name="z">The text's z-position</param>
/// <param name="font">The texts font</param>
/// <param name="x">The texts x-position</param>
/// <param name="y">The texts y-position</param>
/// <param name="z">The texts z-position</param>
/// <param name="color">The text color</param>
public static void DrawText(string text, float h, float x, float y, float z, SColorF color)
public static void DrawText(string text, CFont font, float x, float y, float z, SColorF color)
{
if (h <= 0f)
if (font.Height <= 0f || text == "")
return;
if (text == "")
return;
Height = h;
CFont font = _GetCurrentFont();
CFontStyle fontStyle = _GetFontStyle(font);
float dx = x;
foreach (char chr in text)
{
font.DrawGlyph(chr, dx, y, z, color);
dx += font.GetWidth(chr);
fontStyle.DrawGlyph(chr, font.Height, dx, y, z, color);
dx += fontStyle.GetWidth(chr, font.Height);
}
}
public static void DrawTextReflection(string text, float h, float x, float y, float z, SColorF color, float rspace, float rheight)
public static void DrawTextReflection(string text, CFont font, float x, float y, float z, SColorF color, float rspace, float rheight)
{
if (h <= 0f)
if (font.Height <= 0f || text == "")
return;
if (text == "")
return;
Height = h;
CFont font = _GetCurrentFont();
CFontStyle fontStyle = _GetFontStyle(font);
float dx = x;
foreach (char chr in text)
{
font.DrawGlyphReflection(chr, dx, y, z, color, rspace, rheight);
dx += font.GetWidth(chr);
fontStyle.DrawGlyphReflection(chr, font.Height, dx, y, z, color, rspace, rheight);
dx += fontStyle.GetWidth(chr, font.Height);
}
}
public static void DrawText(string text, float h, float x, float y, float z, SColorF color, float begin, float end)
public static void DrawText(string text, CFont font, float x, float y, float z, SColorF color, float begin, float end)
{
if (h <= 0f)
if (font.Height <= 0f || text == "")
return;
if (text == "")
return;
Height = h;
float dx = x;
float w = GetTextWidth(text);
float w = GetTextWidth(text, font);
if (w <= 0f)
return;
float x1 = x + w * begin;
float x2 = x + w * end;
float xStart = x + w * begin;
float xEnd = x + w * end;
float xCur = x;
CFont font = _GetCurrentFont();
CFontStyle fontStyle = _GetFontStyle(font);
foreach (char chr in text)
{
float w2 = font.GetWidth(chr);
float b = (x1 - dx) / w2;
float w2 = fontStyle.GetWidth(chr, font.Height);
float b = (xStart - xCur) / w2;
if (b < 1f)
{
if (b < 0f)
b = 0f;
float e = (x2 - dx) / w2;
float e = (xEnd - xCur) / w2;
if (e > 0f)
{
if (e > 1f)
e = 1f;
font.DrawGlyph(chr, dx, y, z, color, b, e);
fontStyle.DrawGlyph(chr, font.Height, xCur, y, z, color, b, e);
}
}
dx += w2;
xCur += w2;
}
}
#endregion DrawText
public static FontStyle GetFontStyle()
{
switch (Style)
{
case EStyle.Normal:
return FontStyle.Regular;
case EStyle.Italic:
return FontStyle.Italic;
case EStyle.Bold:
return FontStyle.Bold;
case EStyle.BoldItalic:
return FontStyle.Bold | FontStyle.Italic;
default:
return FontStyle.Regular;
}
}
public static void SetFont(string fontName)
{
int index = _GetPartyFontIndex(PartyModeID, fontName);
if (index < 0)
index = _GetThemeFontIndex(CConfig.Theme, fontName);
if (index < 0)
index = _GetFontIndex(fontName);
if (index >= 0)
_CurrentFont = index;
}
/// <summary>
/// Calculates the bounds for a CText object
/// </summary>
@@ -232,94 +182,172 @@ namespace Vocaluxe.Base.Fonts
/// <returns>RectangleF object containing the bounds</returns>
public static RectangleF GetTextBounds(CText text)
{
return GetTextBounds(text, text.Height);
return new RectangleF(text.X, text.Y, GetTextWidth(text.TranslatedText, text.Font), GetTextHeight(text.TranslatedText, text.Font));
}
public static Font GetSystemFont(CFont font)
{
return _GetFontStyle(font).GetSystemFont(font.Height);
}
public static float GetOutlineSize(CFont font)
{
return _FontFamilies[_GetFontIndex(font.Name)].Outline;
}
public static SColorF GetOutlineColor(CFont font)
{
return _FontFamilies[_GetFontIndex(font.Name)].OutlineColor;
}
private static CFontStyle _GetFontStyle(CFont font)
{
int index = _GetFontIndex(font.Name);
switch (font.Style)
{
case EStyle.Normal:
return _FontFamilies[index].Normal;
case EStyle.Italic:
return _FontFamilies[index].Italic;
case EStyle.Bold:
return _FontFamilies[index].Bold;
case EStyle.BoldItalic:
return _FontFamilies[index].BoldItalic;
}
throw new ArgumentException("Invalid Style: " + font.Style);
}
public static float GetTextWidth(string text, CFont font)
{
CFontStyle fontStyle = _GetFontStyle(font);
return text.Sum(chr => fontStyle.GetWidth(chr, font.Height));
}
public static float GetTextHeight(string text, CFont font)
{
CFontStyle fontStyle = _GetFontStyle(font);
return text == "" ? 0 : text.Select(chr => fontStyle.GetHeight(chr, font.Height)).Max();
}
private static int _GetFontIndex(string fontName)
{
if (fontName != "")
{
int index = _GetPartyFontIndex(fontName, PartyModeID);
if (index < 0)
index = _GetThemeFontIndex(fontName, CConfig.Theme);
if (index >= 0)
return index;
for (int i = 0; i < _FontFamilies.Count; i++)
{
if (_FontFamilies[i].Name == fontName)
return i;
}
if (!_LoggedMissingFonts.Contains(fontName))
{
_LoggedMissingFonts.Add(fontName);
CLog.LogError("Font \"" + fontName + "\" not found!");
}
}
else
CLog.LogError("Empty fontName requested", false, false, new Exception());
if (_FontFamilies.Count == 0)
CLog.LogError("No fonts found!", true, true);
return 0;
}
private static int _GetThemeFontIndex(string fontName, string themeName)
{
Debug.Assert(fontName != "" && themeName != "");
for (int i = 0; i < _FontFamilies.Count; i++)
{
if (_FontFamilies[i].Name == fontName && _FontFamilies[i].ThemeName == themeName)
return i;
}
return -1;
}
private static int _GetPartyFontIndex(string fontName, int partyModeID)
{
Debug.Assert(fontName != "");
for (int i = 0; i < _FontFamilies.Count; i++)
{
if (_FontFamilies[i].PartyModeID == partyModeID && _FontFamilies[i].Name == fontName)
return i;
}
return -1;
}
/// <summary>
/// Calculates the bounds for a CText object
/// Load default fonts
/// </summary>
/// <param name="text">The CText object of which the bounds should be calculated for</param>
/// <param name="height">The height of the CText object</param>
/// <returns>RectangleF object containing the bounds</returns>
public static RectangleF GetTextBounds(CText text, float height)
/// <returns></returns>
private static bool _LoadDefaultFonts()
{
float oldHeight = Height;
int oldFont = _CurrentFont;
EStyle oldStyle = Style;
Height = height;
SetFont(text.Font);
Style = text.Style;
var result = new RectangleF(text.X, text.Y, GetTextWidth(CLanguage.Translate(text.Text, text.TranslationID)),
GetTextHeight(CLanguage.Translate(text.Text, text.TranslationID)));
//restore old values
Height = oldHeight;
_CurrentFont = oldFont;
Style = oldStyle;
return result;
CXMLReader xmlReader = CXMLReader.OpenFile(Path.Combine(CSettings.ProgramFolder, CSettings.FolderNameFonts, CSettings.FileNameFonts));
if (xmlReader == null)
return false;
return _LoadFontFile(xmlReader, Path.Combine(CSettings.ProgramFolder, CSettings.FolderNameFonts));
}
public static float GetTextWidth(string text)
/// <summary>
/// Loads theme fonts from skin file
/// </summary>
public static bool LoadThemeFonts(string themeName, string fontFolder, CXMLReader xmlReader)
{
CFont font = _GetCurrentFont();
return text.Sum(chr => font.GetWidth(chr));
bool ok = _LoadFontFile(xmlReader, fontFolder, themeName);
CLog.StartBenchmark("BuildGlyphs");
_BuildGlyphs();
CLog.StopBenchmark("BuildGlyphs");
return ok;
}
public static float GetTextHeight(string text)
/// <summary>
/// Loads party mode fonts from skin file
/// </summary>
public static bool LoadPartyModeFonts(int partyModeID, string fontFolder, CXMLReader xmlReader)
{
//return TextRenderer.MeasureText(text, GetFont()).Height;
CFont font = _GetCurrentFont();
return text == "" ? 0 : text.Select(font.GetHeight).Max();
bool ok = _LoadFontFile(xmlReader, fontFolder, "", partyModeID);
CLog.StartBenchmark("BuildGlyphs");
_BuildGlyphs();
CLog.StopBenchmark("BuildGlyphs");
return ok;
}
private static void _LoadFontFiles(CXMLReader xmlReader, string fontFolder, string themeName = "", int partyModeId = -1)
private static bool _LoadFontFile(CXMLReader xmlReader, string fontFolder, string themeName = "", int partyModeId = -1)
{
string value = string.Empty;
string value;
int i = 1;
while (xmlReader.GetValue("//root/Fonts/Font" + i + "/Folder", out value, value))
while (xmlReader.GetValue("//root/Fonts/Font" + i + "/Folder", out value))
{
var sf = new SFont {Folder = value, IsThemeFont = themeName != "", ThemeName = themeName, PartyModeID = partyModeId};
var sf = new SFontFamily {Folder = value, ThemeName = themeName, PartyModeID = partyModeId};
bool ok = true;
string name;
ok &= xmlReader.GetValue("//root/Fonts/Font" + i + "/Name", out name, value);
sf.Name = name;
ok &= xmlReader.GetValue("//root/Fonts/Font" + i + "/FileNormal", out value, value);
sf.FileNormal = value;
value = Path.Combine(fontFolder, Path.Combine(sf.Folder, value));
var f = new CFont(value);
sf.Normal = f;
ok &= xmlReader.GetValue("//root/Fonts/Font" + i + "/FileItalic", out value, value);
sf.FileItalic = value;
value = Path.Combine(fontFolder, Path.Combine(sf.Folder, value));
f = new CFont(value);
sf.Italic = f;
ok &= xmlReader.GetValue("//root/Fonts/Font" + i + "/FileBold", out value, value);
sf.FileBold = value;
value = Path.Combine(fontFolder, Path.Combine(sf.Folder, value));
f = new CFont(value);
sf.Bold = f;
ok &= xmlReader.GetValue("//root/Fonts/Font" + i + "/FileBoldItalic", out value, value);
sf.FileBoldItalic = value;
value = Path.Combine(fontFolder, Path.Combine(sf.Folder, value));
f = new CFont(value);
sf.BoldItalic = f;
sf.Outline = 0f;
ok &= xmlReader.TryGetFloatValue("//root/Fonts/Font" + i + "/Outline", ref sf.Outline);
sf.OutlineColor = new SColorF(0f, 0f, 0f, 1f);
ok &= xmlReader.TryGetFloatValue("//root/Fonts/Font" + i + "/OutlineColorR", ref sf.OutlineColor.R);
ok &= xmlReader.TryGetFloatValue("//root/Fonts/Font" + i + "/OutlineColorG", ref sf.OutlineColor.G);
ok &= xmlReader.TryGetFloatValue("//root/Fonts/Font" + i + "/OutlineColorB", ref sf.OutlineColor.B);
ok &= xmlReader.TryGetFloatValue("//root/Fonts/Font" + i + "/OutlineColorA", ref sf.OutlineColor.A);
ok &= xmlReader.GetValue("//root/Fonts/Font" + i + "/Name", out sf.Name);
ok &= xmlReader.GetValue("//root/Fonts/Font" + i + "/FileNormal", out sf.FileNormal);
ok &= xmlReader.GetValue("//root/Fonts/Font" + i + "/FileItalic", out sf.FileItalic);
ok &= xmlReader.GetValue("//root/Fonts/Font" + i + "/FileBold", out sf.FileBold);
ok &= xmlReader.GetValue("//root/Fonts/Font" + i + "/FileBoldItalic", out sf.FileBoldItalic);
ok &= xmlReader.TryGetNormalizedFloatValue("//root/Fonts/Font" + i + "/Outline", ref sf.Outline);
ok &= xmlReader.TryGetColorFromRGBA("//root/Fonts/Font" + i + "/OutlineColor", ref sf.OutlineColor);
if (ok)
_Fonts.Add(sf);
{
sf.Normal = new CFontStyle(Path.Combine(fontFolder, sf.Folder, sf.FileNormal), EStyle.Normal, sf.Outline, sf.OutlineColor);
sf.Italic = new CFontStyle(Path.Combine(fontFolder, sf.Folder, sf.FileItalic), EStyle.Italic, sf.Outline, sf.OutlineColor);
sf.Bold = new CFontStyle(Path.Combine(fontFolder, sf.Folder, sf.FileBold), EStyle.Bold, sf.Outline, sf.OutlineColor);
sf.BoldItalic = new CFontStyle(Path.Combine(fontFolder, sf.Folder, sf.FileBoldItalic), EStyle.BoldItalic, sf.Outline, sf.OutlineColor);
_FontFamilies.Add(sf);
}
else
{
string fontTypes;
@@ -330,170 +358,80 @@ namespace Vocaluxe.Base.Fonts
else
fontTypes = "basic fonts";
CLog.LogError("Error loading " + fontTypes + ": Error in Font" + i);
return false;
}
i++;
}
}
/// <summary>
/// Load default fonts
/// </summary>
/// <returns></returns>
private static void _LoadFontList()
{
CXMLReader xmlReader = CXMLReader.OpenFile(Path.Combine(CSettings.ProgramFolder, CSettings.FolderNameFonts, CSettings.FileNameFonts));
if (xmlReader == null)
return;
_LoadFontFiles(xmlReader, Path.Combine(CSettings.ProgramFolder, CSettings.FolderNameFonts));
}
/// <summary>
/// Loads theme fonts from skin file
/// </summary>
public static void LoadThemeFonts(string themeName, string fontFolder, CXMLReader xmlReader)
{
_LoadFontFiles(xmlReader, fontFolder, themeName);
CLog.StartBenchmark("BuildGlyphs");
_BuildGlyphs();
CLog.StopBenchmark("BuildGlyphs");
}
/// <summary>
/// Loads party mode fonts from skin file
/// </summary>
public static void LoadPartyModeFonts(int partyModeID, string fontFolder, CXMLReader xmlReader)
{
_LoadFontFiles(xmlReader, fontFolder, "", partyModeID);
CLog.StartBenchmark("BuildGlyphs");
_BuildGlyphs();
CLog.StopBenchmark("BuildGlyphs");
return true;
}
public static void SaveThemeFonts(string themeName, XmlWriter writer)
{
if (_Fonts.Count == 0)
if (_FontFamilies.Count == 0)
return;
int index = 0;
writer.WriteStartElement("Fonts");
int fontNr = 1;
bool setStart = false;
while (index < _Fonts.Count)
foreach (SFontFamily font in _FontFamilies)
{
if (_Fonts[index].IsThemeFont && _Fonts[index].ThemeName == themeName)
if (font.ThemeName == themeName)
{
if (!setStart)
{
writer.WriteStartElement("Fonts");
setStart = true;
}
writer.WriteStartElement("Font" + fontNr);
writer.WriteElementString("Name", _Fonts[index].Name);
writer.WriteElementString("Folder", _Fonts[index].Folder);
writer.WriteElementString("Name", font.Name);
writer.WriteElementString("Folder", font.Folder);
writer.WriteElementString("Outline", _Fonts[index].Outline.ToString("#0.00"));
writer.WriteElementString("OutlineColorR", _Fonts[index].OutlineColor.R.ToString("#0.00"));
writer.WriteElementString("OutlineColorG", _Fonts[index].OutlineColor.G.ToString("#0.00"));
writer.WriteElementString("OutlineColorB", _Fonts[index].OutlineColor.B.ToString("#0.00"));
writer.WriteElementString("OutlineColorA", _Fonts[index].OutlineColor.A.ToString("#0.00"));
writer.WriteElementString("Outline", font.Outline.ToString("#0.00"));
writer.WriteStartElement("OutlineColor");
writer.WriteElementString("R", font.OutlineColor.R.ToString("#0.00"));
writer.WriteElementString("G", font.OutlineColor.G.ToString("#0.00"));
writer.WriteElementString("B", font.OutlineColor.B.ToString("#0.00"));
writer.WriteElementString("A", font.OutlineColor.A.ToString("#0.00"));
writer.WriteEndElement();
writer.WriteElementString("FileNormal", _Fonts[index].FileNormal);
writer.WriteElementString("FileBold", _Fonts[index].FileBold);
writer.WriteElementString("FileItalic", _Fonts[index].FileItalic);
writer.WriteElementString("FileBoldItalic", _Fonts[index].FileBoldItalic);
writer.WriteElementString("FileNormal", font.FileNormal);
writer.WriteElementString("FileBold", font.FileBold);
writer.WriteElementString("FileItalic", font.FileItalic);
writer.WriteElementString("FileBoldItalic", font.FileBoldItalic);
writer.WriteEndElement();
fontNr++;
}
index++;
}
if (setStart)
writer.WriteEndElement();
writer.WriteEndElement();
}
public static void UnloadThemeFonts(string themeName)
{
int index = 0;
while (index < _Fonts.Count)
while (index < _FontFamilies.Count)
{
if (_Fonts[index].IsThemeFont && _Fonts[index].ThemeName == themeName)
if (_FontFamilies[index].ThemeName == themeName)
{
_Fonts[index].Normal.UnloadGlyphs();
_Fonts[index].Italic.UnloadGlyphs();
_Fonts[index].Bold.UnloadGlyphs();
_Fonts[index].BoldItalic.UnloadGlyphs();
_Fonts.RemoveAt(index);
_FontFamilies[index].Dispose();
_FontFamilies.RemoveAt(index);
}
else
index++;
}
}
private static int _GetFontIndex(string fontName)
{
for (int i = 0; i < _Fonts.Count; i++)
{
if (!_Fonts[i].IsThemeFont && _Fonts[i].Name == fontName)
return i;
}
return -1;
}
private static int _GetThemeFontIndex(string themeName, string fontName)
{
if (themeName == "" || fontName == "")
return -1;
for (int i = 0; i < _Fonts.Count; i++)
{
if (_Fonts[i].IsThemeFont && _Fonts[i].Name == fontName && _Fonts[i].ThemeName == themeName)
return i;
}
return -1;
}
private static int _GetPartyFontIndex(int partyModeID, string fontName)
{
if (partyModeID == -1 || fontName == "")
return -1;
for (int i = 0; i < _Fonts.Count; i++)
{
if (!_Fonts[i].IsThemeFont && _Fonts[i].PartyModeID == partyModeID && _Fonts[i].Name == fontName)
return i;
}
return -1;
}
private static void _BuildGlyphs()
{
const string text = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
for (int i = 0; i < _Fonts.Count; i++)
foreach (SFontFamily fontFamily in _FontFamilies)
{
_CurrentFont = i;
foreach (char chr in text)
{
Style = EStyle.Normal;
_Fonts[_CurrentFont].Normal.GetOrAddGlyph(chr);
Style = EStyle.Bold;
_Fonts[_CurrentFont].Bold.GetOrAddGlyph(chr);
Style = EStyle.Italic;
_Fonts[_CurrentFont].Italic.GetOrAddGlyph(chr);
Style = EStyle.BoldItalic;
_Fonts[_CurrentFont].BoldItalic.GetOrAddGlyph(chr);
fontFamily.Normal.GetOrAddGlyph(chr, -1);
fontFamily.Bold.GetOrAddGlyph(chr, -1);
fontFamily.Italic.GetOrAddGlyph(chr, -1);
fontFamily.BoldItalic.GetOrAddGlyph(chr, -1);
}
}
Style = EStyle.Normal;
SetFont("Normal");
}
}
}
+21 -25
View File
@@ -31,31 +31,18 @@ namespace Vocaluxe.Base.Fonts
{
class CGlyph
{
private CTexture _Texture;
private CTextureRef _Texture;
private readonly SizeF _BoundingBox;
private readonly RectangleF _DrawBounding;
public readonly float MaxHeight;
public float Width
{
get { return _BoundingBox.Width * _GetFactor(); }
}
public float Height
{
get { return _BoundingBox.Height * _GetFactor(); }
}
public CGlyph(char chr, float maxHeight)
public CGlyph(char chr, CFontStyle fontStyle, float maxHeight)
{
MaxHeight = maxHeight;
float oldHeight = CFonts.Height;
float outline = CFonts.Outline;
float outlineSize = outline * maxHeight;
float outlineSize = fontStyle.Outline * maxHeight;
string chrString = chr.ToString();
CFonts.Height = maxHeight;
Font fo = CFonts.GetFont();
Font fo = fontStyle.GetSystemFont(maxHeight);
SizeF fullSize;
Size bmpSize;
using (Graphics g = Graphics.FromHwnd(IntPtr.Zero))
@@ -64,7 +51,7 @@ namespace Vocaluxe.Base.Fonts
if (chr != ' ')
{
//Gets exact height and width for drawing more than 1 char. But width is to small to draw char on bitmap as e.g. italic chars will get cropped
_BoundingBox = g.MeasureString(chrString, fo, -1, new StringFormat(StringFormat.GenericTypographic));
_BoundingBox = g.MeasureString(chrString, fo, -1, StringFormat.GenericTypographic);
// ReSharper disable CompareOfFloatsByEqualityOperator
if (_BoundingBox.Height == 0)
// ReSharper restore CompareOfFloatsByEqualityOperator
@@ -105,7 +92,7 @@ namespace Vocaluxe.Base.Fonts
float emSize = fo.Size * fo.FontFamily.GetCellAscent(fo.Style) / fo.FontFamily.GetEmHeight(fo.Style);
path.AddString(chrString, fo.FontFamily, (int)fo.Style, emSize, point, new StringFormat());
using (var pen = new Pen(CFonts.OutlineColor.AsColor(), outlineSize))
using (var pen = new Pen(fontStyle.OutlineColor.AsColor(), outlineSize))
{
pen.LineJoin = LineJoin.Round;
g.DrawPath(pen, path);
@@ -134,7 +121,6 @@ namespace Vocaluxe.Base.Fonts
}
}
}
CFonts.Height = oldHeight;
}
public void UnloadTexture()
@@ -142,15 +128,25 @@ namespace Vocaluxe.Base.Fonts
CDraw.RemoveTexture(ref _Texture);
}
private float _GetFactor()
private float _GetFactor(float fontHeight)
{
return CFonts.Height / _BoundingBox.Height;
return fontHeight / _BoundingBox.Height;
}
public void GetTextureAndRect(float x, float y, float z, out CTexture texture, out SRectF rect)
public float GetWidth(float fontHeight)
{
return _BoundingBox.Width * _GetFactor(fontHeight);
}
public float GetHeight(float fontHeight)
{
return _BoundingBox.Height * _GetFactor(fontHeight);
}
public void GetTextureAndRect(float fontHeight, float x, float y, float z, out CTextureRef texture, out SRectF rect)
{
texture = _Texture;
float factor = _GetFactor();
float factor = _GetFactor(fontHeight);
x += _DrawBounding.X * factor;
y += _DrawBounding.Y * factor;
float h = _DrawBounding.Height * factor;
@@ -161,7 +157,7 @@ namespace Vocaluxe.Base.Fonts
private static Rectangle _GetRealBounds(Bitmap bmp)
{
int minX = 0, maxX = bmp.Width - 1, minY = 0;
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
BitmapData bmpData = bmp.LockBits(bmp.GetRect(), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
int values = bmpData.Width * bmp.Height;
var rgbValues = new Int32[values];
Marshal.Copy(bmpData.Scan0, rgbValues, 0, values);
+1
View File
@@ -16,6 +16,7 @@
#endregion
using System;
using System.Drawing;
using System.Runtime.InteropServices;
namespace Vocaluxe
+84 -82
View File
@@ -22,6 +22,7 @@ using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using Vocaluxe.Base;
using VocaluxeLib;
using VocaluxeLib.Draw;
#if WIN
using System.Data.SQLite;
@@ -34,28 +35,29 @@ namespace Vocaluxe.Lib.Database
{
public class CCoverDB : CDatabaseBase
{
//You have to lock all actions using cover connection or transaction, otherwhise order is not guaranted
private readonly object _CoverMutex = new object();
private SQLiteTransaction _TransactionCover;
public CCoverDB(string filePath) : base(filePath) {}
public override bool Init()
{
if (!base.Init())
return false;
lock (_Mutex)
{
if (!base.Init())
return false;
if (_Version < 0)
return _CreateCoverDB();
if (_Version < CSettings.DatabaseCoverVersion)
throw new NotImplementedException("Upgrading of cover DB not implemented");
if (_Version < 0)
return _CreateCoverDB();
if (_Version < CSettings.DatabaseCoverVersion)
throw new NotImplementedException("Upgrading of cover DB not implemented");
}
return true;
}
public override void Close()
{
//Do commit and close atomicly otherwhise we may loose changes
lock (_CoverMutex)
lock (_Mutex)
{
_CommitCovers();
@@ -63,7 +65,7 @@ namespace Vocaluxe.Lib.Database
}
}
public bool GetCover(string coverPath, ref CTexture tex, int maxSize)
public bool GetCover(string coverPath, ref CTextureRef tex, int maxSize)
{
if (_Connection == null)
return false;
@@ -73,7 +75,7 @@ namespace Vocaluxe.Lib.Database
return false;
}
lock (_CoverMutex)
lock (_Mutex)
{
//Double check here because we may have just closed our connection
if (_Connection == null)
@@ -81,7 +83,7 @@ namespace Vocaluxe.Lib.Database
using (var command = new SQLiteCommand(_Connection))
{
command.CommandText = "SELECT id, width, height FROM Cover WHERE [Path] = @path";
command.Parameters.Add("@path", DbType.String, 0).Value = coverPath;
command.Parameters.Add("@path", DbType.String).Value = coverPath;
SQLiteDataReader reader = command.ExecuteReader();
@@ -100,81 +102,81 @@ namespace Vocaluxe.Lib.Database
if (reader.HasRows)
{
reader.Read();
byte[] data = _GetBytes(reader);
byte[] data2 = _GetBytes(reader);
reader.Dispose();
tex = CDraw.EnqueueTexture(w, h, data);
tex = CDraw.EnqueueTexture(w, h, data2);
return true;
}
}
else
{
if (reader != null)
reader.Close();
if (_TransactionCover == null)
_TransactionCover = _Connection.BeginTransaction();
Bitmap origin;
try
{
origin = new Bitmap(coverPath);
}
catch (Exception)
{
CLog.LogError("Error loading Texture: " + coverPath);
return false;
}
int w = maxSize;
int h = maxSize;
byte[] data;
try
{
if (origin.Width >= origin.Height && origin.Width > w)
h = (int)Math.Round((float)w / origin.Width * origin.Height);
else if (origin.Height > origin.Width && origin.Height > h)
w = (int)Math.Round((float)h / origin.Height * origin.Width);
using (var bmp = new Bitmap(w, h))
{
using (Graphics g = Graphics.FromImage(bmp))
g.DrawImage(origin, new Rectangle(0, 0, w, h));
data = new byte[w * h * 4];
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
Marshal.Copy(bmpData.Scan0, data, 0, w * h * 4);
bmp.UnlockBits(bmpData);
}
}
finally
{
origin.Dispose();
}
tex = CDraw.EnqueueTexture(w, h, data);
command.CommandText = "INSERT INTO Cover (Path, width, height) VALUES (@path, @w, @h)";
command.Parameters.Add("@w", DbType.Int32).Value = w;
command.Parameters.Add("@h", DbType.Int32).Value = h;
command.Parameters.Add("@path", DbType.String, 0).Value = coverPath;
command.CommandText = "DELETE FROM Cover WHERE id = @id";
command.Parameters.Add("@id", DbType.Int32).Value = id;
command.ExecuteNonQuery();
}
if (reader != null)
reader.Close();
}
}
command.CommandText = "SELECT id FROM Cover WHERE [Path] = @path";
command.Parameters.Add("@path", DbType.String, 0).Value = coverPath;
reader = command.ExecuteReader();
// At this point we do not have a mathing entry in the CoverDB (either no Data found and deleted or nothing at all)
// We break out of the lock to do the bitmap loading and resizing here to allow multithreaded loading
if (reader != null)
{
reader.Read();
int id = reader.GetInt32(0);
reader.Dispose();
command.CommandText = "INSERT INTO CoverData (CoverID, Data) VALUES (@id, @data)";
command.Parameters.Add("@id", DbType.Int32).Value = id;
command.Parameters.Add("@data", DbType.Binary, 20).Value = data;
command.ExecuteReader();
return true;
}
Bitmap origin = CHelper.LoadBitmap(coverPath);
if (origin == null)
return false;
Size size = origin.GetSize();
if (size.Width > maxSize || size.Height > maxSize)
{
size = CHelper.FitInBounds(new SRectF(0, 0, maxSize, maxSize, 0), (float)size.Width / size.Height, EAspect.LetterBox).SizeI;
Bitmap tmp = origin.Resize(size);
origin.Dispose();
origin = tmp;
}
byte[] data;
try
{
data = new byte[size.Width * size.Height * 4];
BitmapData bmpData = origin.LockBits(origin.GetRect(), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
Marshal.Copy(bmpData.Scan0, data, 0, data.Length);
origin.UnlockBits(bmpData);
}
finally
{
origin.Dispose();
}
tex = CDraw.EnqueueTexture(size.Width, size.Height, data);
lock (_Mutex)
{
//Double check here because we may have just closed our connection
if (_Connection == null)
return false;
if (_TransactionCover == null)
_TransactionCover = _Connection.BeginTransaction();
using (var command = new SQLiteCommand(_Connection))
{
command.CommandText = "INSERT INTO Cover (Path, width, height) VALUES (@path, @w, @h)";
command.Parameters.Add("@w", DbType.Int32).Value = size.Width;
command.Parameters.Add("@h", DbType.Int32).Value = size.Height;
command.Parameters.Add("@path", DbType.String).Value = coverPath;
command.ExecuteNonQuery();
command.CommandText = "SELECT id FROM Cover WHERE [Path] = @path";
command.Parameters.Add("@path", DbType.String).Value = coverPath;
SQLiteDataReader reader = command.ExecuteReader();
if (reader != null)
{
reader.Read();
int id = reader.GetInt32(0);
reader.Dispose();
command.CommandText = "INSERT INTO CoverData (CoverID, Data) VALUES (@id, @data)";
command.Parameters.Add("@id", DbType.Int32).Value = id;
command.Parameters.Add("@data", DbType.Binary).Value = data;
command.ExecuteNonQuery();
return true;
}
}
}
@@ -183,7 +185,7 @@ namespace Vocaluxe.Lib.Database
public void CommitCovers()
{
lock (_CoverMutex)
lock (_Mutex)
{
_CommitCovers();
}
+48 -31
View File
@@ -17,7 +17,6 @@
using System;
using System.IO;
using Vocaluxe.Base;
#if WIN
using System.Data.SQLite;
@@ -27,61 +26,72 @@ using Mono.Data.Sqlite;
namespace Vocaluxe.Lib.Database
{
public class CDatabaseBase
public abstract class CDatabaseBase
{
protected readonly string _FilePath;
protected SQLiteConnection _Connection;
//You have to lock all actions using connection or transaction, otherwhise order is not guaranted
protected readonly object _Mutex = new object();
protected int _Version; //Version of the database (value of row "Value" in table "Version") or -1 if none
public CDatabaseBase(string filePath)
protected CDatabaseBase(string filePath)
{
_FilePath = filePath;
}
public virtual bool Init()
{
_Connection = new SQLiteConnection("Data Source=" + _FilePath);
try
lock (_Mutex)
{
_Connection.Open();
}
catch (Exception)
{
_Connection.Dispose();
_Connection = null;
return false;
}
using (var command = new SQLiteCommand(_Connection))
{
command.CommandText = "SELECT Value FROM Version";
SQLiteDataReader reader = null;
if (_Connection != null)
return false;
_Connection = new SQLiteConnection("Data Source=" + _FilePath);
try
{
reader = command.ExecuteReader();
_Connection.Open();
}
catch (Exception)
{
_Connection.Dispose();
_Connection = null;
return false;
}
catch (Exception) {}
if (reader == null || !reader.Read() || reader.FieldCount == 0)
_Version = -1;
else
_Version = reader.GetInt32(0);
using (var command = new SQLiteCommand(_Connection))
{
command.CommandText = "SELECT Value FROM Version";
if (reader != null)
reader.Dispose();
SQLiteDataReader reader = null;
try
{
reader = command.ExecuteReader();
}
catch (Exception) {}
if (reader == null || !reader.Read() || reader.FieldCount == 0)
_Version = -1;
else
_Version = reader.GetInt32(0);
if (reader != null)
reader.Dispose();
}
}
return true;
}
public virtual void Close()
{
if (_Connection != null)
lock (_Mutex)
{
_Connection.Dispose();
_Connection = null;
if (_Connection != null)
{
_Connection.Dispose();
_Connection = null;
}
}
}
@@ -92,6 +102,13 @@ namespace Vocaluxe.Lib.Database
return t70.Ticks;
}
/// <summary>
/// Reads the contents of a field as a byte array <br />
/// Assumes you did the locking!
/// </summary>
/// <param name="reader"></param>
/// <param name="field">Field number to read from (default=first)</param>
/// <returns></returns>
protected static byte[] _GetBytes(SQLiteDataReader reader, int field = 0)
{
const int chunkSize = 2 * 1024;
+1 -1
View File
@@ -66,7 +66,7 @@ namespace Vocaluxe.Lib.Database
return true;
}
public bool GetCreditsRessource(string fileName, ref CTexture tex)
public bool GetCreditsRessource(string fileName, ref CTextureRef tex)
{
if (_Connection == null)
return false;
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+198
View File
@@ -0,0 +1,198 @@
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using Vocaluxe.Base;
namespace Vocaluxe.Lib.Draw
{
public delegate bool MessageEventHandler(ref Message m);
public interface IFormHook
{
MessageEventHandler OnMessage { set; }
}
abstract class CDrawBaseWindows<TTextureType> : CDrawBase<TTextureType> where TTextureType : CTextureBase, IDisposable
{
private struct SClientRect
{
public Point Location;
public int Width;
public int Height;
}
protected Form _Form;
private SClientRect _Restore;
protected Size _SizeBeforeMinimize;
public override void Unload()
{
base.Unload();
try
{
_Form.Close();
}
catch {}
}
protected void _CenterToScreen()
{
Screen screen = Screen.FromControl(_Form);
_Form.Location = new Point((screen.WorkingArea.Width - _Form.Width) / 2,
(screen.WorkingArea.Height - _Form.Height) / 2);
}
private static bool _OnMessageAvoidScreenOff(ref Message m)
{
switch (m.Msg)
{
case 0x112: // WM_SYSCOMMAND
switch ((int)m.WParam & 0xFFF0)
{
case 0xF100: // SC_KEYMENU
m.Result = IntPtr.Zero;
return false;
case 0xF140: // SC_SCREENSAVER
case 0xF170: // SC_MONITORPOWER
return false;
}
break;
}
return true;
}
protected override void _EnterFullScreen()
{
Debug.Assert(!_Fullscreen);
_Fullscreen = true;
_Restore.Location = _Form.Location;
_Restore.Width = _Form.Width;
_Restore.Height = _Form.Height;
_Form.FormBorderStyle = FormBorderStyle.None;
Screen screen = Screen.FromControl(_Form);
_Form.DesktopBounds = new Rectangle(screen.Bounds.Location, new Size(screen.Bounds.Width, screen.Bounds.Height));
if (_Form.WindowState == FormWindowState.Maximized)
{
_Form.WindowState = FormWindowState.Normal;
_DoResize();
_Form.WindowState = FormWindowState.Maximized;
}
else
_DoResize();
}
protected override void _LeaveFullScreen()
{
Debug.Assert(_Fullscreen);
_Fullscreen = false;
_Form.FormBorderStyle = FormBorderStyle.Sizable;
_Form.DesktopBounds = new Rectangle(_Restore.Location, new Size(_Restore.Width, _Restore.Height));
}
#region form event handlers
private void _OnClose(object sender, CancelEventArgs e)
{
_Run = false;
}
private void _OnLoad(object sender, EventArgs e)
{
_ClearScreen();
}
protected virtual void _OnResize(object sender, EventArgs e)
{
_DoResize();
}
#region mouse event handlers
protected void _OnMouseMove(object sender, MouseEventArgs e)
{
_Mouse.MouseMove(e);
}
protected void _OnMouseWheel(object sender, MouseEventArgs e)
{
_Mouse.MouseWheel(e);
}
protected void _OnMouseDown(object sender, MouseEventArgs e)
{
_Mouse.MouseDown(e);
}
protected void _OnMouseUp(object sender, MouseEventArgs e)
{
_Mouse.MouseUp(e);
}
protected void _OnMouseLeave(object sender, EventArgs e)
{
_Mouse.Visible = false;
Cursor.Show();
}
protected void _OnMouseEnter(object sender, EventArgs e)
{
Cursor.Hide();
_Mouse.Visible = true;
}
#endregion
#region keyboard event handlers
protected void _OnPreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
_OnKeyDown(sender, new KeyEventArgs(e.KeyData));
}
protected void _OnKeyDown(object sender, KeyEventArgs e)
{
_Keys.KeyDown(e);
}
protected void _OnKeyPress(object sender, KeyPressEventArgs e)
{
_Keys.KeyPress(e);
}
protected void _OnKeyUp(object sender, KeyEventArgs e)
{
_Keys.KeyUp(e);
}
#endregion keyboard event handlers
#endregion
public override bool Init()
{
if (!base.Init())
return false;
_Form.Icon = new Icon(Path.Combine(CSettings.ProgramFolder, CSettings.FileNameIcon));
_Form.Text = CSettings.GetFullVersionText();
((IFormHook)_Form).OnMessage = _OnMessageAvoidScreenOff;
_Form.Closing += _OnClose;
_Form.Resize += _OnResize;
_Form.Load += _OnLoad;
_SizeBeforeMinimize = _Form.ClientSize;
_CenterToScreen();
return true;
}
public override void MainLoop()
{
_Form.Show();
base.MainLoop();
_Form.Hide();
}
}
}
+56 -58
View File
@@ -44,7 +44,8 @@ namespace Vocaluxe.Lib.Draw
private bool _TopMost;
private Rectangle _Bounds;
private readonly Dictionary<int, CTexture> _Textures = new Dictionary<int, CTexture>();
private readonly Dictionary<int, CTextureRef> _Textures = new Dictionary<int, CTextureRef>();
private readonly Dictionary<string, CTextureRef> _TextureCache = new Dictionary<string, CTextureRef>();
private readonly List<Bitmap> _Bitmaps = new List<Bitmap>();
private readonly Color _ClearColor = Color.DarkBlue;
@@ -64,7 +65,6 @@ namespace Vocaluxe.Lib.Draw
_G = Graphics.FromImage(_Backbuffer);
_G.Clear(Color.DarkBlue);
Paint += _OnPaintEvent;
Closing += _OnClosingEvent;
KeyDown += _OnKeyDownEvent;
KeyPress += _OnKeyPressEvent;
@@ -107,8 +107,6 @@ namespace Vocaluxe.Lib.Draw
frontBuffer.DrawImage(_Backbuffer, new Rectangle(x, y, w, h), new Rectangle(0, 0, _Backbuffer.Width, _Backbuffer.Height), GraphicsUnit.Pixel);
}
private void _OnPaintEvent(object sender, PaintEventArgs e) {}
#region FullScreenStuff
private void _ToggleFullScreen()
{
@@ -234,6 +232,7 @@ namespace Vocaluxe.Lib.Draw
if (_Run)
{
ClearScreen();
_Run = _Run && CGraphics.Draw();
_Run = CGraphics.UpdateGameLogic(_Keys, _Mouse);
_FlipBuffer();
@@ -279,11 +278,11 @@ namespace Vocaluxe.Lib.Draw
_G.Clear(_ClearColor);
}
public CTexture CopyScreen()
public CTextureRef CopyScreen()
{
var bmp = new Bitmap(_Backbuffer);
_Bitmaps.Add(bmp);
CTexture texture = _GetNewTexture(bmp.Width, bmp.Height);
CTextureRef texture = _GetNewTexture(bmp.GetSize());
// Add to Texture List
_Textures[texture.ID] = texture;
@@ -291,9 +290,9 @@ namespace Vocaluxe.Lib.Draw
return texture;
}
public void CopyScreen(ref CTexture texture)
public void CopyScreen(ref CTextureRef texture)
{
if (!_TextureExists(texture) || texture.W2 != GetScreenWidth() || texture.H2 != GetScreenHeight())
if (!_TextureExists(texture) || texture.OrigSize.Width != GetScreenWidth() || texture.OrigSize.Height != GetScreenHeight())
{
RemoveTexture(ref texture);
texture = CopyScreen();
@@ -309,20 +308,15 @@ namespace Vocaluxe.Lib.Draw
_Backbuffer.Save(file, ImageFormat.Png);
}
public void DrawLine(int a, int r, int g, int b, int w, int x1, int y1, int x2, int y2)
{
_G.DrawLine(new Pen(Color.FromArgb(a, r, g, b), w), new Point(x1, y1), new Point(x2, y2));
}
public void DrawRect(SColorF color, SRectF rect) {}
public void DrawColor(SColorF color, SRectF rect) {}
public void DrawRectReflection(SColorF color, SRectF rect, float space, float height) {}
public void DrawColorReflection(SColorF color, SRectF rect, float space, float height) {}
public CTexture AddTexture(Bitmap bmp)
public CTextureRef AddTexture(Bitmap bmp)
{
var bmp2 = new Bitmap(bmp);
_Bitmaps.Add(bmp2);
CTexture texture = _GetNewTexture(bmp.Width, bmp.Height);
CTextureRef texture = _GetNewTexture(bmp.GetSize());
// Add to Texture List
_Textures[texture.ID] = texture;
@@ -330,62 +324,84 @@ namespace Vocaluxe.Lib.Draw
return texture;
}
private CTexture _GetNewTexture(int w, int h)
private CTextureRef _GetNewTexture(Size size)
{
return new CTexture(w, h) {ID = _Bitmaps.Count - 1};
return new CTextureRef(_Bitmaps.Count - 1, size);
}
public CTexture AddTexture(string texturePath)
public CTextureRef AddTexture(string texturePath)
{
if (File.Exists(texturePath))
{
foreach (CTexture tex in _Textures.Values)
{
if (tex.TexturePath == texturePath)
return tex;
}
CTextureRef texture;
if (_TextureCache.TryGetValue(texturePath, out texture))
return texture;
using (var bmp = new Bitmap(texturePath))
{
CTexture texture = AddTexture(bmp);
texture.TexturePath = texturePath;
texture = AddTexture(bmp);
_TextureCache.Add(texturePath, texture);
}
return texture;
}
return null;
}
private bool _TextureExists(CTexture texture)
private bool _TextureExists(CTextureRef texture)
{
return texture != null && _Textures.ContainsKey(texture.ID);
}
public void RemoveTexture(ref CTexture texture)
public CTextureRef CopyTexture(CTextureRef textureRef)
{
if (_TextureExists(textureRef))
return AddTexture(_Bitmaps[textureRef.ID]);
return null;
}
public void RemoveTexture(ref CTextureRef texture)
{
if (_TextureExists(texture))
{
_Bitmaps[texture.ID].Dispose();
_Textures.Remove(texture.ID);
texture.SetRemoved();
}
texture = null;
}
public CTexture EnqueueTexture(int w, int h, byte[] data)
public CTextureRef EnqueueTexture(int w, int h, byte[] data)
{
return AddTexture(w, h, data);
}
public CTexture AddTexture(int w, int h, byte[] data)
public CTextureRef EnqueueTexture(string texturePath)
{
return AddTexture(texturePath);
}
public CTextureRef EnqueueTexture(Bitmap bmp)
{
return AddTexture(bmp);
}
public void EnqueueTextureUpdate(CTextureRef textureRef, Bitmap bmp)
{
UpdateTexture(textureRef, bmp);
}
public CTextureRef AddTexture(int w, int h, byte[] data)
{
using (var bmp = new Bitmap(w, h))
{
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
BitmapData bmpData = bmp.LockBits(bmp.GetRect(), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
Marshal.Copy(data, 0, bmpData.Scan0, data.Length);
bmp.UnlockBits(bmpData);
return AddTexture(bmp);
}
}
public bool UpdateTexture(CTexture texture, int w, int h, byte[] data)
public void UpdateTexture(CTextureRef texture, int w, int h, byte[] data)
{
if (_TextureExists(texture))
{
@@ -393,40 +409,22 @@ namespace Vocaluxe.Lib.Draw
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
Marshal.Copy(data, 0, bmpData.Scan0, data.Length);
_Bitmaps[texture.ID].UnlockBits(bmpData);
return true;
}
return false;
}
public bool UpdateOrAddTexture(ref CTexture texture, int w, int h, byte[] data)
public void UpdateTexture(CTextureRef textureRef, Bitmap bmp)
{
if (!UpdateTexture(texture, w, h, data))
{
RemoveTexture(ref texture);
texture = AddTexture(w, h, data);
}
return true;
if (_TextureExists(textureRef))
_Bitmaps[textureRef.ID] = bmp;
}
public void DrawTexture(CTexture texture)
{
if (texture != null)
DrawTexture(texture, texture.Rect, texture.Color);
}
public void DrawTexture(CTexture texture, SRectF rect)
{
if (texture != null)
DrawTexture(texture, rect, texture.Color);
}
public void DrawTexture(CTexture texture, SRectF rect, SColorF color, bool mirrored = false)
public void DrawTexture(CTextureRef texture, SRectF rect, SColorF color, bool mirrored = false)
{
if (texture != null)
DrawTexture(texture, rect, color, rect, mirrored);
}
public void DrawTexture(CTexture texture, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false)
public void DrawTexture(CTextureRef texture, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false)
{
if (!_TextureExists(texture))
return;
@@ -435,9 +433,9 @@ namespace Vocaluxe.Lib.Draw
coloredBitmap.Dispose();
}
public void DrawTexture(CTexture texture, SRectF rect, SColorF color, float begin, float end) {}
public void DrawTexture(CTextureRef texture, SRectF rect, SColorF color, float begin, float end) {}
public void DrawTextureReflection(CTexture texture, SRectF rect, SColorF color, SRectF bounds, float space, float height) {}
public void DrawTextureReflection(CTextureRef texture, SRectF rect, SColorF color, float space, float height) {}
public int GetTextureCount()
{
File diff suppressed because it is too large. Load diff
+96
View File
@@ -0,0 +1,96 @@
using System;
using System.Drawing;
namespace Vocaluxe.Lib.Draw
{
abstract class CTextureBase : IDisposable
{
public int RefCount;
public string TexturePath;
private Size _DataSize;
/// <summary>
/// Size of data used (mostly equal to OrigSize but due to resizing this might change)
/// </summary>
public Size DataSize
{
get { return _DataSize; }
set
{
_DataSize = value;
_CalcRatios();
}
}
/// <summary>
/// texture width (on device), a power of 2 if necessary
/// </summary>
public int W2 { get; protected set; }
/// <summary>
/// texture height (on device), a power of 2 if necessary
/// </summary>
public int H2 { get; protected set; }
/// <summary>
/// Specifies which part of texture memory is actually used
/// </summary>
public float WidthRatio { get; private set; }
/// <summary>
/// Specifies which part of texture memory is actually used
/// </summary>
public float HeightRatio { get; private set; }
/// <summary>
/// True if the texture contains usefull data
/// </summary>
public abstract bool IsLoaded { get; }
/// <summary>
/// Creates a new texture
/// </summary>
/// <param name="dataSize">Size of the data used</param>
/// <param name="texWidth">Width in video memory</param>
/// <param name="texHeight">Height in video memory</param>
protected CTextureBase(Size dataSize, int texWidth = 0, int texHeight = 0)
{
_DataSize = dataSize;
W2 = (texWidth > 0) ? texWidth : dataSize.Width;
H2 = (texHeight > 0) ? texHeight : dataSize.Height;
_CalcRatios();
}
private void _CalcRatios()
{
// OpenGL has a problem with partial (NPOT) textures, so we remove 1 pixel
if (_DataSize.Width == W2)
WidthRatio = 1f;
else
{
int mod = 0;
if (_DataSize.Width > 1)
mod = -1;
WidthRatio = (float)(_DataSize.Width + mod) / W2;
}
if (_DataSize.Height == H2)
HeightRatio = 1f;
else
{
int mod = 0;
if (_DataSize.Height > 1)
mod = -1;
HeightRatio = (float)(_DataSize.Height + mod) / H2;
}
}
private bool _IsDisposed;
public virtual void Dispose()
{
if (_IsDisposed)
throw new ObjectDisposedException(GetType().Name);
RefCount = 0;
_IsDisposed = true;
}
}
}
+19 -19
View File
@@ -32,30 +32,30 @@ namespace Vocaluxe.Lib.Draw
int GetTextureCount();
void ClearScreen();
CTexture CopyScreen();
void CopyScreen(ref CTexture texture);
CTextureRef CopyScreen();
void CopyScreen(ref CTextureRef texture);
void MakeScreenShot();
CTexture AddTexture(string texturePath);
CTexture AddTexture(Bitmap bitmap);
CTexture AddTexture(int w, int h, byte[] data);
CTexture EnqueueTexture(int w, int h, byte[] data);
bool UpdateTexture(CTexture texture, int w, int h, byte[] data);
bool UpdateOrAddTexture(ref CTexture texture, int w, int h, byte[] data);
void RemoveTexture(ref CTexture texture);
CTextureRef AddTexture(string texturePath);
CTextureRef AddTexture(Bitmap bitmap);
CTextureRef AddTexture(int w, int h, byte[] data);
void UpdateTexture(CTextureRef texture, Bitmap bmp);
void UpdateTexture(CTextureRef texture, int w, int h, byte[] data);
CTextureRef EnqueueTexture(string texturePath);
CTextureRef EnqueueTexture(Bitmap bmp);
CTextureRef EnqueueTexture(int w, int h, byte[] data);
void EnqueueTextureUpdate(CTextureRef textureRef, Bitmap bmp);
CTextureRef CopyTexture(CTextureRef textureRef);
void RemoveTexture(ref CTextureRef texture);
// Basic Draw Methods
void DrawLine(int a, int r, int g, int b, int w, int x1, int y1, int x2, int y2);
void DrawColor(SColorF color, SRectF rect);
void DrawColorReflection(SColorF color, SRectF rect, float space, float height);
void DrawRect(SColorF color, SRectF rect);
void DrawRectReflection(SColorF color, SRectF rect, float space, float height);
void DrawTexture(CTexture texture);
void DrawTexture(CTexture texture, SRectF rect);
void DrawTexture(CTexture texture, SRectF rect, SColorF color, bool mirrored = false);
void DrawTexture(CTexture texture, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false);
void DrawTexture(CTexture texture, SRectF rect, SColorF color, float begin, float end);
void DrawTexture(CTextureRef texture, SRectF rect, SColorF color, bool mirrored = false);
void DrawTexture(CTextureRef texture, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false);
void DrawTexture(CTextureRef texture, SRectF rect, SColorF color, float begin, float end);
void DrawTextureReflection(CTexture texture, SRectF rect, SColorF color, SRectF bounds, float space, float height);
void DrawTextureReflection(CTextureRef texture, SRectF rect, SColorF color, float space, float height);
}
}
+1
View File
@@ -24,6 +24,7 @@ using Vocaluxe.Base;
using VocaluxeLib;
using VocaluxeLib.Menu;
using VocaluxeLib.Songs;
using VocaluxeLib.Xml;
namespace Vocaluxe.Lib.Playlist
{
@@ -17,6 +17,7 @@
using Gst;
using System;
using Vocaluxe.Base;
namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
{
@@ -26,13 +27,20 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
{
if (_Initialized)
return false;
#if ARCH_X86
var gstreamerEnvVar = Environment.GetEnvironmentVariable("GSTREAMER_1_0_ROOT_X86", EnvironmentVariableTarget.User);
const string varName = "GSTREAMER_1_0_ROOT_X86";
#endif
#if ARCH_X64
var gstreamerEnvVar = Environment.GetEnvironmentVariable("GSTREAMER_1_0_ROOT_X86_64", EnvironmentVariableTarget.User);
const string varName = "GSTREAMER_1_0_ROOT_X86_64";
#endif
var dllDirectory = gstreamerEnvVar + "bin\\";
string gstreamerEnvVar = Environment.GetEnvironmentVariable(varName, EnvironmentVariableTarget.User);
if (gstreamerEnvVar == null)
{
CLog.LogError("Gstreamer not found! Make sure you installed it correctly and if it set the environment variable '" + varName + "'!", true);
return false;
}
string dllDirectory = gstreamerEnvVar + "bin\\";
COSFunctions.AddEnvironmentPath(dllDirectory);
Application.Init();
+1 -1
View File
@@ -102,7 +102,7 @@ namespace Vocaluxe.Lib.Video.Acinerella
Finished = true;
}
public bool GetFrame(ref CTexture frame, float time, out float videoTime)
public bool GetFrame(ref CTextureRef frame, float time, out float videoTime)
{
if (Finished)
{
@@ -193,7 +193,7 @@ namespace Vocaluxe.Lib.Video.Acinerella
/// <param name="time">Maximum start time for frame</param>
/// <param name="finished">Set to whether there are no more frames (stream finished, no loop, future calls will always return false)</param>
/// <returns>True if a new frame was gotten</returns>
public bool GetFrame(ref CTexture frame, ref float time, out bool finished)
public bool GetFrame(ref CTextureRef frame, ref float time, out bool finished)
{
bool result;
if (Math.Abs(_LastShownTime - time) < _FrameDuration && frame != null) //Check 1 frame difference
@@ -206,7 +206,10 @@ namespace Vocaluxe.Lib.Video.Acinerella
CFramebuffer.CFrame curFrame = _FindFrame(time);
if (curFrame != null)
{
CDraw.UpdateOrAddTexture(ref frame, _Width, _Height, curFrame.Data);
if (frame == null)
frame = CDraw.AddTexture(_Width, _Height, curFrame.Data);
else
CDraw.UpdateTexture(frame, _Width, _Height, curFrame.Data);
if (!_Paused)
curFrame.SetRead();
time = curFrame.Time;
+1 -1
View File
@@ -69,7 +69,7 @@ namespace Vocaluxe.Lib.Video
return _Decoder.Count;
}
public bool GetFrame(int streamID, ref CTexture frame, float time, out float videoTime)
public bool GetFrame(int streamID, ref CTextureRef frame, float time, out float videoTime)
{
CDecoder decoder;
if (_Decoder.TryGetValue(streamID, out decoder))
+1 -1
View File
@@ -73,7 +73,7 @@ namespace Vocaluxe.Lib.Video
/// </param>
/// <param name="videoTime">The actual position in s of the returned frame. Should be ~ time+VideoGap</param>
/// <returns>True if frame is valid, false: frame and videoTime might be unchanged or invalid</returns>
bool GetFrame(int streamID, ref CTexture frame, float time, out float videoTime);
bool GetFrame(int streamID, ref CTextureRef frame, float time, out float videoTime);
/// <summary>
/// Seeks to given position
+5 -2
View File
@@ -201,13 +201,16 @@ namespace Vocaluxe.Lib.Webcam
}
}
public bool GetFrame(ref CTexture frame)
public bool GetFrame(ref CTextureRef frame)
{
lock (_MutexData)
{
if (_Data != null && _Data.Length == _Width * _Height * 4 && _NewFrameAvailable)
{
CDraw.UpdateOrAddTexture(ref frame, _Width, _Height, _Data);
if (frame == null)
frame = CDraw.AddTexture(_Width, _Height, _Data);
else
CDraw.UpdateTexture(frame, _Width, _Height, _Data);
_NewFrameAvailable = false;
return true;
}
+1 -1
View File
@@ -58,7 +58,7 @@ namespace Vocaluxe.Lib.Webcam
/// </summary>
/// <param name="frame"></param>
/// <returns></returns>
bool GetFrame(ref CTexture frame);
bool GetFrame(ref CTextureRef frame);
/// <summary>
/// Gets the last captured frame as a bitma
+15 -13
View File
@@ -81,7 +81,7 @@ namespace Vocaluxe
{
// Init Log
CLog.Init();
CLog.StartBenchmark("Init Program");
if (!CProgrammHelper.CheckRequirements())
return;
CProgrammHelper.Init();
@@ -173,17 +173,11 @@ namespace Vocaluxe
Application.DoEvents();
// Init Font
CLog.StartBenchmark("Init Font");
CFonts.Init();
CLog.StopBenchmark("Init Font");
Application.DoEvents();
// Load Cover
CLog.StartBenchmark("Init Cover");
CCover.Init();
CLog.StopBenchmark("Init Cover");
// Init Fonts
CLog.StartBenchmark("Init Fonts");
if (!CFonts.Init())
throw new CLoadingException("fonts");
CLog.StopBenchmark("Init Fonts");
Application.DoEvents();
@@ -195,6 +189,13 @@ namespace Vocaluxe
Application.DoEvents();
// Load Cover
CLog.StartBenchmark("Init Cover");
CCover.Init();
CLog.StopBenchmark("Init Cover");
Application.DoEvents();
// Init Screens
CLog.StartBenchmark("Init Screens");
CGraphics.Init();
@@ -235,6 +236,7 @@ namespace Vocaluxe
//Only reasonable point to call GC.Collect() because initialization may cause lots of garbage
//Rely on GC doing its job afterwards and call Dispose methods where appropriate
GC.Collect();
CLog.StopBenchmark("Init Program");
}
catch (Exception e)
{
@@ -250,7 +252,6 @@ namespace Vocaluxe
// Start Main Loop
if (_SplashScreen != null)
_SplashScreen.Close();
CVocaluxeServer.Start();
CDraw.MainLoop();
}
@@ -264,6 +265,7 @@ namespace Vocaluxe
CVocaluxeServer.Close();
CGraphics.Close();
CCover.Close();
CFonts.Close();
CBackgroundMusic.Close();
CWebcam.Close();
CDataBase.Close();
@@ -195,7 +195,7 @@ namespace Vocaluxe.Screens
return false;
_Statics[_StaticCover].Texture = CBackgroundMusic.Cover;
if (CBackgroundMusic.VideoEnabled && _VideoPreview && CBackgroundMusic.SongHasVideo)
CDraw.DrawTexture(_Statics[_StaticCover], CBackgroundMusic.GetVideoTexture(), EAspect.Crop);
CDraw.DrawTexture(CBackgroundMusic.GetVideoTexture(), _Statics[_StaticCover].Rect, EAspect.Crop);
_Buttons[_ButtonPause].Visible = CBackgroundMusic.IsPlaying;
_Buttons[_ButtonPlay].Visible = !CBackgroundMusic.IsPlaying;
_Texts[_TextCurrentSong].Text = CBackgroundMusic.ArtistAndTitle;
+5 -5
View File
@@ -33,11 +33,11 @@ namespace Vocaluxe.Screens
get { return 1; }
}
private CTexture _QRServerAddress;
private CTexture _QRAndroidLink;
private CTexture _QRSymbianLink;
private CTexture _QRWebOSLink;
private CTexture _QRWindowsPhoneLink;
private CTextureRef _QRServerAddress;
private CTextureRef _QRAndroidLink;
private CTextureRef _QRSymbianLink;
private CTextureRef _QRWebOSLink;
private CTextureRef _QRWindowsPhoneLink;
private const string _StaticQRServer = "StaticQRServer";
private const string _StaticQRAndroid = "StaticQRAndroid";
+16 -16
View File
@@ -126,21 +126,21 @@ namespace Vocaluxe.Screens
private List<string[]> _Paragraphs;
private List<CText> _ParagraphTexts;
private CTexture _TexLogo;
private CTexture _TexPerfectNoteStar;
private CTextureRef _TexLogo;
private CTextureRef _TexPerfectNoteStar;
private CTexture _TexRedDot;
private CTexture _TexBlueDot;
private CTextureRef _TexRedDot;
private CTextureRef _TexBlueDot;
private CTexture _TexNameBrunzel;
private CTexture _TexNameDarkice;
private CTexture _TexNameFlokuep;
private CTexture _TexNameFlamefire;
private CTexture _TexNameMesand;
private CTexture _TexNameBohning;
private CTexture _TexNameBabene03;
private CTexture _TexNamePantero;
private CTexture _TexNamePinky007;
private CTextureRef _TexNameBrunzel;
private CTextureRef _TexNameDarkice;
private CTextureRef _TexNameFlokuep;
private CTextureRef _TexNameFlamefire;
private CTextureRef _TexNameMesand;
private CTextureRef _TexNameBohning;
private CTextureRef _TexNameBabene03;
private CTextureRef _TexNamePantero;
private CTextureRef _TexNamePinky007;
public override void Init()
{
@@ -286,12 +286,12 @@ namespace Vocaluxe.Screens
return GetNewParticleEffect(numStars, partColor, rect, _TexPerfectNoteStar, partSize, EParticleType.Star);
}
private void _AddNewCreditName(CTexture texture, int particleOffsetX, int particleOffsetY, bool bigParticles)
private void _AddNewCreditName(CTextureRef texture, int particleOffsetX, int particleOffsetY, bool bigParticles)
{
bool isRight = _CreditNames.Count % 2 == 0;
int partRectSize = bigParticles ? 25 : 20;
int partCount = bigParticles ? 8 : 6;
CTexture texDot = isRight ? _TexRedDot : _TexBlueDot;
CTextureRef texDot = isRight ? _TexRedDot : _TexBlueDot;
CStatic image = GetNewStatic(texture, new SColorF(1, 1, 1, 1), new SRectF(-1, -1, 400, 120, -4));
@@ -360,7 +360,7 @@ namespace Vocaluxe.Screens
base.Draw();
//Draw background
CDraw.DrawColor(new SColorF(0, 0.18f, 0.474f, 1), new SRectF(0, 0, CSettings.RenderW, CSettings.RenderH, 0));
CDraw.DrawRect(new SColorF(0, 0.18f, 0.474f, 1), new SRectF(0, 0, CSettings.RenderW, CSettings.RenderH, 0));
//Draw stars
_StarsBlue.Draw();
+1 -1
View File
@@ -55,7 +55,7 @@ namespace Vocaluxe.Screens
{"EqualizerPlayer1", "EqualizerPlayer2", "EqualizerPlayer3", "EqualizerPlayer4", "EqualizerPlayer5", "EqualizerPlayer6"};
private readonly string[] _SelectSlideDuetPlayer = new string[]
{"SelectSlideDuetPlayer1", "SelectSlideDuetPlayer2", "SelectSlideDuetPlayer3", "SelectSlideDuetPlayer4", "SelectSlideDuetPlayer5", "SelectSlideDuetPlayer6"};
private readonly CTexture[] _OriginalPlayerAvatarTextures = new CTexture[CSettings.MaxNumPlayer];
private readonly CTextureRef[] _OriginalPlayerAvatarTextures = new CTextureRef[CSettings.MaxNumPlayer];
private bool _SelectingKeyboardActive;
private bool _SelectingFast;
+1 -1
View File
@@ -49,7 +49,7 @@ namespace Vocaluxe.Screens
private const string _TextWebcamResolution = "TextWebcamResolution";
private SWebcamConfig _Config;
private CTexture _WebcamTexture;
private CTextureRef _WebcamTexture;
private int _DeviceNr;
private int _CapabilityNr;
+1 -1
View File
@@ -64,7 +64,7 @@ namespace Vocaluxe.Screens
private EEditMode _EditMode;
private CTexture _WebcamTexture;
private CTextureRef _WebcamTexture;
private Bitmap _Snapshot;
public override void Init()
+14 -17
View File
@@ -99,9 +99,9 @@ namespace Vocaluxe.Screens
private const float _Volume = 100f;
private int _CurrentVideo = -1;
private EAspect _VideoAspect = EAspect.Crop;
private CTexture _CurrentVideoTexture;
private CTexture _CurrentWebcamFrameTexture;
private CTexture _Background;
private CTextureRef _CurrentVideoTexture;
private CTextureRef _CurrentWebcamFrameTexture;
private CTextureRef _Background;
private float _CurrentTime;
private float _FinishTime;
@@ -274,7 +274,7 @@ namespace Vocaluxe.Screens
case Keys.V:
if (_VideoAspect == EAspect.Zoom2)
_VideoAspect = 0;
_VideoAspect = EAspect.Crop;
else
_VideoAspect++;
@@ -463,7 +463,7 @@ namespace Vocaluxe.Screens
{
if (_Active)
{
CTexture background;
CTextureRef background;
var aspect = EAspect.Crop;
if (_CurrentVideo != -1 && CConfig.VideosInSongs == EOffOn.TR_CONFIG_ON && !_Webcam)
{
@@ -479,11 +479,8 @@ namespace Vocaluxe.Screens
background = _Background;
if (background != null)
{
var bounds = new RectangleF(0, 0, CSettings.RenderW, CSettings.RenderH);
RectangleF rect;
CHelper.SetRect(bounds, out rect, background.OrigAspect, aspect);
CDraw.DrawTexture(background, new SRectF(rect.X, rect.Y, rect.Width, rect.Height, 0f),
background.Color, new SRectF(bounds.X, bounds.Y, bounds.Width, bounds.Height, 0f));
var bounds = new SRectF(0, 0, CSettings.RenderW, CSettings.RenderH, 0);
CDraw.DrawTexture(background, bounds, aspect, background.Color);
}
else if (_SlideShow != null)
_SlideShow.Draw();
@@ -1004,13 +1001,13 @@ namespace Vocaluxe.Screens
float partSeconds = timeDiff - fullSeconds;
_Texts[_TextMedleyCountdown].Visible = true;
_Texts[_TextMedleyCountdown].Text = fullSeconds.ToString();
float h = partSeconds * CSettings.RenderH;
float w = CFonts.GetTextBounds(_Texts[_TextMedleyCountdown], h).Width;
float x = CSettings.RenderW / 2 - w / 2;
float y = CSettings.RenderH / 2 - h / 2;
_Texts[_TextMedleyCountdown].Font.Height = partSeconds * CSettings.RenderH;
RectangleF textBounds = CFonts.GetTextBounds(_Texts[_TextMedleyCountdown]);
float x = CSettings.RenderW / 2 - textBounds.Width / 2;
float y = CSettings.RenderH / 2 - textBounds.Height / 2;
_Texts[_TextMedleyCountdown].X = x;
_Texts[_TextMedleyCountdown].Y = y;
_Texts[_TextMedleyCountdown].Height = h;
}
else
_Texts[_TextMedleyCountdown].Visible = false;
@@ -1216,8 +1213,8 @@ namespace Vocaluxe.Screens
}
else
{
_Statics[_StaticSongText].Color.A = 10f - t / 3f;
_Texts[_TextSongName].Color.A = 10f - t / 3f;
_Statics[_StaticSongText].Color.A = (10f - t) / 3f;
_Texts[_TextSongName].Color.A = (10f - t) / 3f;
}
}
else
+1 -1
View File
@@ -413,7 +413,7 @@ namespace Vocaluxe.Screens
_SongMenu.Active = !_PlaylistActive;
_ToggleSongOptions(ESongOptionsView.None);
}
else if (CHelper.IsInBounds(_SongMenu.Rect, mouseEvent.X, mouseEvent.Y))
else if (CHelper.IsInBounds(_SongMenu.Rect, mouseEvent))
{
_PlaylistActive = false;
_Playlist.Selected = _PlaylistActive;
+5 -1
View File
@@ -216,6 +216,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Base\CBackgroundMusic.cs" />
<Compile Include="Base\CNoCoverGenerator.cs" />
<Compile Include="Base\CPlaylistElement.cs" />
<Compile Include="Base\CRecord.cs" />
<Compile Include="Base\CVideoPlayer.cs" />
@@ -224,6 +225,9 @@
<Compile Include="Lib\Database\CDatabaseBase.cs" />
<Compile Include="Lib\Database\CHighscoreDB.cs" />
<Compile Include="Lib\Database\CResourceDB.cs" />
<Compile Include="Lib\Draw\CDrawBase.cs" />
<Compile Include="Lib\Draw\CDrawBaseWindows.cs" />
<Compile Include="Lib\Draw\CTextureBase.cs" />
<Compile Include="Lib\Sound\Playback\CAudioStreamBase.cs" />
<Compile Include="Lib\Sound\Playback\CPlaybackBase.cs" />
<Compile Include="Lib\Sound\Playback\CRingBuffer.cs" />
@@ -241,7 +245,7 @@
<Compile Include="Base\CDraw.cs" />
<Compile Include="Lib\Sound\Playback\PortAudio\CPt1.cs" />
<Compile Include="Lib\Sound\Playback\PortAudio\CSyncTimer.cs" />
<Compile Include="Base\Fonts\CFont.cs" />
<Compile Include="Base\Fonts\CFontStyle.cs" />
<Compile Include="Base\CGame.cs" />
<Compile Include="Base\CController.cs" />
<Compile Include="Base\CLanguage.cs" />
+39
View File
@@ -0,0 +1,39 @@
using System.Text;
namespace VocaluxeLib
{
static class CEncoding
{
public static Encoding GetEncoding(this string encodingName)
{
switch (encodingName)
{
case "AUTO":
return Encoding.Default;
case "CP1250":
return Encoding.GetEncoding(1250);
case "CP1252":
return Encoding.GetEncoding(1252);
case "LOCALE":
return Encoding.Default;
case "UTF8":
return Encoding.UTF8;
default:
return Encoding.Default;
}
}
public static string GetEncodingName(this Encoding enc)
{
string result = "UTF8";
if (enc.CodePage == 1250)
result = "CP1250";
if (enc.CodePage == 1252)
result = "CP1252";
return result;
}
}
}
+95
View File
@@ -0,0 +1,95 @@
using System;
using System.Collections.Generic;
using System.Xml.Serialization;
namespace VocaluxeLib
{
public interface IFontObserver
{
void FontChanged();
}
public struct SThemeFont
{
public string Name;
public EStyle Style;
public float Size;
}
public class CFont
{
private string _Name;
private EStyle _Style;
private float _Height;
private readonly List<IFontObserver> _Observers = new List<IFontObserver>();
public string Name
{
get { return _Name; }
set
{
if (_Name == value)
return;
_Name = value;
foreach (IFontObserver observer in _Observers)
observer.FontChanged();
}
}
public EStyle Style
{
get { return _Style; }
set
{
if (_Style == value)
return;
_Style = value;
foreach (IFontObserver observer in _Observers)
observer.FontChanged();
}
}
public float Height
{
get { return _Height; }
set
{
if (Math.Abs(_Height - value) < 0.001)
return;
_Height = value;
foreach (IFontObserver observer in _Observers)
observer.FontChanged();
}
}
public CFont()
{
_Name = "Normal";
_Style = EStyle.Normal;
_Height = 25f;
}
public CFont(SThemeFont font)
{
_Name = font.Name;
_Style = font.Style;
_Height = font.Size;
}
public CFont(string fontFamily, EStyle style, float h)
{
_Name = fontFamily;
_Style = style;
_Height = h;
}
public void AddObserver(IFontObserver observer)
{
if (!_Observers.Contains(observer))
_Observers.Add(observer);
}
public void RemoveObserver(IFontObserver observer)
{
_Observers.Remove(observer);
}
}
}
+61 -115
View File
@@ -17,11 +17,9 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Text;
namespace VocaluxeLib
{
@@ -64,46 +62,6 @@ namespace VocaluxeLib
return (int)result;
}
/// <summary>
/// Makes sure val is between min and max
/// Asserts that min&lt;=max
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="val"></param>
/// <param name="min"></param>
/// <param name="max"></param>
/// <returns>Clamped value</returns>
public static T Clamp<T>(this T val, T min, T max) where T : IComparable<T>
{
Debug.Assert(min.CompareTo(max) <= 0);
if (val.CompareTo(min) < 0)
return min;
if (val.CompareTo(max) > 0)
return max;
return val;
}
/// <summary>
/// Makes sure val is between min and max but also handles the case where min&gt;max
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="val"></param>
/// <param name="min"></param>
/// <param name="max"></param>
/// <param name="preferMin"></param>
/// <returns>Clamped value</returns>
public static T Clamp<T>(this T val, T min, T max, bool preferMin) where T : IComparable<T>
{
if (min.CompareTo(max) > 0)
{
if (preferMin)
max = min;
else
min = max;
}
return Clamp(val, min, max);
}
/// <summary>
/// Concat strings into one string with ", " as separator.
/// </summary>
@@ -120,90 +78,88 @@ namespace VocaluxeLib
return result;
}
public static void SetRect(SRectF bounds, out SRectF rect, float rectAspect, EAspect aspect)
/// <summary>
/// Places a rect within the bounds maintaining the aspectRatio and using the given aspect
/// </summary>
/// <param name="bounds">Bounds to fit the rect in</param>
/// <param name="aspectRatio">The original aspectRatio of the rect/image/...</param>
/// <param name="aspect">
/// Crop: Fit fully in bounds cutting off overhanging parts (same on both sides)<br />
/// LetterBox: Fit the long side possibly leaving some space on the other (rect will be centered)<br />
/// StretcH: Just fit the rect in the bounds (rect=bounds)
/// </param>
public static SRectF FitInBounds(SRectF bounds, float aspectRatio, EAspect aspect)
{
var bounds2 = new RectangleF(bounds.X, bounds.Y, bounds.W, bounds.H);
RectangleF rect2;
SetRect(bounds2, out rect2, rectAspect, aspect);
if (aspect == EAspect.Stretch)
return bounds;
rect = new SRectF(rect2.X, rect2.Y, rect2.Width, rect2.Height, bounds.Z);
}
float boundsAspectRatio = bounds.W / bounds.H;
public static void SetRect(RectangleF bounds, out RectangleF rect, float rectAspect, EAspect aspect)
{
float boundsW = bounds.Width;
float boundsH = bounds.Height;
float boundsAspect = boundsW / boundsH;
float scaledWidth;
float scaledHeight;
float scaledWidth, scaledHeight;
switch (aspect)
{
case EAspect.Crop:
if (boundsAspect >= rectAspect)
if (boundsAspectRatio >= aspectRatio)
{
scaledWidth = boundsW;
scaledHeight = boundsW / rectAspect;
scaledWidth = bounds.W;
scaledHeight = bounds.W / aspectRatio;
}
else
{
scaledHeight = boundsH;
scaledWidth = boundsH * rectAspect;
scaledHeight = bounds.H;
scaledWidth = bounds.H * aspectRatio;
}
break;
case EAspect.Zoom1:
if (boundsAspect >= rectAspect)
if (boundsAspectRatio >= aspectRatio)
{
scaledWidth = boundsW * 1.33f;
scaledHeight = boundsW * 1.33f / rectAspect;
scaledWidth = bounds.W * 1.33f;
scaledHeight = bounds.W * 1.33f / aspectRatio;
}
else
{
scaledHeight = boundsH / 1.33f;
scaledWidth = boundsH / 1.33f * rectAspect;
scaledHeight = bounds.H / 1.33f;
scaledWidth = bounds.H / 1.33f * aspectRatio;
}
break;
case EAspect.Zoom2:
if (boundsAspect >= rectAspect)
if (boundsAspectRatio >= aspectRatio)
{
scaledWidth = boundsW * 1.17f;
scaledHeight = boundsW * 1.17f / rectAspect;
scaledWidth = bounds.W * 1.17f;
scaledHeight = bounds.W * 1.17f / aspectRatio;
}
else
{
scaledHeight = boundsH / 1.17f;
scaledWidth = boundsH / 1.17f * rectAspect;
scaledHeight = bounds.H / 1.17f;
scaledWidth = bounds.H / 1.17f * aspectRatio;
}
break;
case EAspect.LetterBox:
if (boundsAspect <= rectAspect)
if (boundsAspectRatio <= aspectRatio)
{
scaledWidth = boundsW;
scaledHeight = boundsW / rectAspect;
scaledWidth = bounds.W;
scaledHeight = bounds.W / aspectRatio;
}
else
{
scaledHeight = boundsH;
scaledWidth = boundsH * rectAspect;
scaledHeight = bounds.H;
scaledWidth = bounds.H * aspectRatio;
}
break;
default:
scaledWidth = boundsW;
scaledHeight = boundsH;
break;
return bounds;
}
float left = (bounds.W - scaledWidth) / 2 + bounds.X;
float top = (bounds.H - scaledHeight) / 2 + bounds.Y;
float left = (boundsW - scaledWidth) / 2 + bounds.Left;
float upper = (boundsH - scaledHeight) / 2 + bounds.Top;
rect = new RectangleF(left, upper, scaledWidth, scaledHeight);
return new SRectF(left, top, scaledWidth, scaledHeight, bounds.Z);
}
/// <summary>
/// Returns a list with all files in the given path that match a given pattern
/// </summary>
/// <param name="path">Path to search for</param>
/// <param name="path">Path to search</param>
/// <param name="searchPattern">Pattern to match (e.g. "*.jpg")</param>
/// <param name="recursive">Search directories recursively</param>
/// <param name="fullpath">False for just file names, True for full path</param>
@@ -301,7 +257,7 @@ namespace VocaluxeLib
public static bool IsInBounds(SRectF bounds, int x, int y)
{
return (bounds.X <= x) && (bounds.X + bounds.W >= x) && (bounds.Y <= y) && (bounds.Y + bounds.H >= y);
return ((float)x).IsInRange(bounds.X, bounds.X + bounds.W) && ((float)y).IsInRange(bounds.Y, bounds.Y + bounds.H);
}
/// <summary>
@@ -331,40 +287,30 @@ namespace VocaluxeLib
{
return (n * n + n) / 2;
}
}
static class CEncoding
{
public static Encoding GetEncoding(this string encodingName)
/// <summary>
/// Loads a bitmap from a file logging errors
/// </summary>
/// <param name="filePath">Full path to image file</param>
/// <returns>Bitmap or null on error</returns>
public static Bitmap LoadBitmap(string filePath)
{
switch (encodingName)
if (!File.Exists(filePath))
{
case "AUTO":
return Encoding.Default;
case "CP1250":
return Encoding.GetEncoding(1250);
case "CP1252":
return Encoding.GetEncoding(1252);
case "LOCALE":
return Encoding.Default;
case "UTF8":
return Encoding.UTF8;
default:
return Encoding.Default;
CBase.Log.LogError("Can't find File: " + filePath);
return null;
}
}
public static string GetEncodingName(this Encoding enc)
{
string result = "UTF8";
if (enc.CodePage == 1250)
result = "CP1250";
if (enc.CodePage == 1252)
result = "CP1252";
return result;
Bitmap bmp;
try
{
bmp = new Bitmap(filePath);
}
catch (Exception)
{
CBase.Log.LogError("Error loading bitmap: " + filePath);
return null;
}
return bmp;
}
}
}
-149
View File
@@ -1,149 +0,0 @@
#region license
// This file is part of Vocaluxe.
//
// Vocaluxe 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 3 of the License, or
// (at your option) any later version.
//
// Vocaluxe 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 Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
#endregion
using System.Drawing;
namespace VocaluxeLib.Draw
{
public class CTexture
{
public int ID = -1;
public int PBO;
//Only used by OpenGL (the texture "name" according to the specs)
public int Name = -1;
public string TexturePath = "";
/// <summary>
/// Original size (e.g. of bmp)
/// </summary>
public readonly Size OrigSize;
public float OrigAspect
{
get { return (float)OrigSize.Width / OrigSize.Height; }
}
/// <summary>
/// Current size when drawn
/// </summary>
public SRectF Rect;
public SColorF Color = new SColorF(1f, 1f, 1f, 1f);
private int _W2, _H2;
private readonly bool _UseFullTexture;
/// <summary>
/// Internal texture width (on device), a power of 2 if necessary
/// </summary>
public int W2
{
get { return _W2; }
set
{
_W2 = value;
if (_UseFullTexture)
WidthRatio = 1;
else
WidthRatio = (float)OrigSize.Width / _W2;
}
}
/// <summary>
/// Internal texture height (on device), a power of 2 if necessary
/// </summary>
public int H2
{
get { return _H2; }
set
{
_H2 = value;
if (_UseFullTexture)
HeightRatio = 1;
else
HeightRatio = (float)OrigSize.Height / _H2;
}
}
/// <summary>
/// Internal use. Specifies which part of texture memory is actually used
/// </summary>
public float WidthRatio { get; private set; }
/// <summary>
/// Internal use. Specifies which part of texture memory is actually used
/// </summary>
public float HeightRatio { get; private set; }
/// <summary>
/// Actual texture space used in x direction
/// </summary>
public int UsedWidth
{
get { return (int)(_W2 * WidthRatio); }
}
/// <summary>
/// Actual texture space used in y direction
/// </summary>
public int UsedHeight
{
get { return (int)(_H2 * HeightRatio); }
}
/*
/// <summary>
/// Internal use. Specifies if full texture memory should be used
/// Set to true if you resized the original image to the maximum
/// </summary>
public bool UseFullTexture
{
get { return _UseFullTexture; }
set
{
_UseFullTexture = value;
if (value)
{
WidthRatio = 1;
HeightRatio = 1;
}
else
{
WidthRatio = (float)OrigSize.Width / _W2;
HeightRatio = (float)OrigSize.Height / _H2;
}
}
}
*/
/// <summary>
/// Creates a new texture reference
/// </summary>
/// <param name="origWidth">Original width (Bitmap size)</param>
/// <param name="origHeight">Original height (Bitmap size)</param>
/// <param name="texWidth">Width in video memory</param>
/// <param name="texHeight">Height in video memory</param>
/// <param name="useFullTexture">True if it is using the full size of the video memory (no blank parts due to Pow-2-Issue)</param>
public CTexture(int origWidth, int origHeight, int texWidth = 0, int texHeight = 0, bool useFullTexture = false)
{
OrigSize = new Size(origWidth, origHeight);
Rect = new SRectF(0f, 0f, origWidth, origHeight, 0f);
_UseFullTexture = useFullTexture;
//IMPORTANT: Use setter here to calculate ratios!
W2 = (texWidth > 0) ? texWidth : origWidth;
H2 = (texHeight > 0) ? texHeight : origHeight;
}
}
}
+87
View File
@@ -0,0 +1,87 @@
#region license
// This file is part of Vocaluxe.
//
// Vocaluxe 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 3 of the License, or
// (at your option) any later version.
//
// Vocaluxe 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 Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
#endregion
using System;
using System.Drawing;
namespace VocaluxeLib.Draw
{
/// <summary>
/// Reference to a texture in the drawing driver
/// </summary>
public class CTextureRef : IDisposable
{
public int ID { get; private set; }
/// <summary>
/// Size of original image (e.g. of bmp)
/// </summary>
public Size OrigSize;
public float OrigAspect
{
get { return (float)OrigSize.Width / OrigSize.Height; }
}
/// <summary>
/// Current size when drawn
/// </summary>
public SRectF Rect;
public SColorF Color = new SColorF(1f, 1f, 1f, 1f);
/// <summary>
/// Creates a new texture reference
/// </summary>
/// <param name="id">ID of the texture</param>
/// <param name="origSize">Original size (Bitmap size)</param>
public CTextureRef(int id, Size origSize)
{
ID = id;
OrigSize = origSize;
Rect = new SRectF(0f, 0f, origSize.Width, origSize.Height, 0f);
}
~CTextureRef()
{
Dispose();
}
public void Dispose()
{
if (ID >= 0)
{
//Free textures that are no longer referenced
CTextureRef tmp = this;
CBase.Drawing.RemoveTexture(ref tmp);
}
SetRemoved();
}
/// <summary>
/// Call this from the graphics driver to denote that this reference is remove and no longer valid <br />
/// This avoids the finalizer
/// </summary>
public void SetRemoved()
{
if (ID < 0)
throw new ObjectDisposedException(GetType().Name);
ID = -1;
GC.SuppressFinalize(this);
}
}
}
+7
View File
@@ -48,6 +48,13 @@ namespace VocaluxeLib
Zoom2
}
public enum EGeneralAlignment
{
Middle,
Start,
End
}
public enum EAlignment
{
Left,
+103 -18
View File
@@ -17,13 +17,71 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
namespace VocaluxeLib
{
public static class CExtensions
{
/// <summary>
/// Makes sure val is between min and max
/// Asserts that min&lt;=max
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="val"></param>
/// <param name="min"></param>
/// <param name="max"></param>
/// <returns>Clamped value</returns>
public static T Clamp<T>(this T val, T min, T max) where T : IComparable<T>
{
Debug.Assert(min.CompareTo(max) <= 0);
if (val.CompareTo(min) < 0)
return min;
if (val.CompareTo(max) > 0)
return max;
return val;
}
/// <summary>
/// Makes sure val is between min and max but also handles the case where min&gt;max
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="val"></param>
/// <param name="min"></param>
/// <param name="max"></param>
/// <param name="preferMin"></param>
/// <returns>Clamped value</returns>
public static T Clamp<T>(this T val, T min, T max, bool preferMin) where T : IComparable<T>
{
if (min.CompareTo(max) > 0)
{
if (preferMin)
max = min;
else
min = max;
}
return Clamp(val, min, max);
}
/// <summary>
/// Checks if the value is in the specified range
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="val"></param>
/// <param name="min"></param>
/// <param name="max"></param>
/// <returns></returns>
public static bool IsInRange<T>(this T val, T min, T max) where T : IComparable<T>
{
Debug.Assert(min.CompareTo(max) <= 0);
return min.CompareTo(val) <= 0 && max.CompareTo(val) >= 0;
}
/// <summary>
/// Resizes the given list to the given size. Removes elements or adds default values
/// </summary>
@@ -91,28 +149,13 @@ namespace VocaluxeLib
return value.IndexOf(other, StringComparison.CurrentCultureIgnoreCase) >= 0;
}
private static Regex _MultipleWhiteSpaceRegEx = new Regex(@" {2,}");
public static string TrimMultipleWs(this string value)
{
if (string.IsNullOrEmpty(value))
return "";
int start = 0;
int len = value.Length;
while (value[start] == ' ')
{
start++;
if (start >= len)
return "";
}
if (start > 0)
start--;
int end = --len;
while (value[end] == ' ')
end--;
if (end < len)
end++;
if (end - start < len)
value = value.Substring(start, end - start + 1);
return value;
return _MultipleWhiteSpaceRegEx.Replace(value, " ");
}
/// <summary>
@@ -134,5 +177,47 @@ namespace VocaluxeLib
rect.H + 2 * rect.H * (scale - 1f),
rect.Z);
}
public static Size GetSize(this Bitmap bmp)
{
return new Size(bmp.Width, bmp.Height);
}
public static Rectangle GetRect(this Bitmap bmp)
{
return Rectangle.Round(new Rectangle(0, 0, bmp.Width, bmp.Height));
}
/// <summary>
/// Resizes the bitmap to the given size creating a copy of it
/// </summary>
/// <param name="bmp"></param>
/// <param name="newSize"></param>
/// <returns>Resized bitmap or null on error</returns>
public static Bitmap Resize(this Bitmap bmp, Size newSize)
{
Bitmap result = null;
try
{
//Create a new Bitmap with the new sizes
result = new Bitmap(newSize.Width, newSize.Height);
//Scale the texture
using (Graphics g = Graphics.FromImage(result))
{
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.SmoothingMode = SmoothingMode.HighQuality;
g.DrawImage(bmp, result.GetRect());
}
}
catch (Exception)
{
if (result != null)
{
result.Dispose();
result = null;
}
}
return result;
}
}
}
+22 -26
View File
@@ -101,8 +101,8 @@ namespace VocaluxeLib
{
string GetThemeScreensPath(int partyModeID);
int GetSkinIndex(int partyModeID);
CTexture GetSkinTexture(string textureName, int partyModeID);
CTexture GetSkinVideoTexture(string videoName, int partyModeID);
CTextureRef GetSkinTexture(string textureName, int partyModeID);
CTextureRef GetSkinVideoTexture(string videoName, int partyModeID);
void SkinVideoResume(string videoName, int partyModeID);
void SkinVideoPause(string videoName, int partyModeID);
@@ -133,26 +133,27 @@ namespace VocaluxeLib
void Play();
void Stop();
CTexture GetVideoTexture();
CTextureRef GetVideoTexture();
void LoadPreview(CSong song, float start = 0f);
void PlayPreview(float start = -1f);
void StopPreview();
}
public interface IDrawing
{
void DrawTexture(CTexture texture, SRectF rect);
void DrawTexture(CTexture texture, SRectF rect, SColorF color);
void DrawTexture(CTexture texture, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false);
void DrawTextureReflection(CTexture texture, SRectF rect, SColorF color, SRectF bounds, float reflectionSpace, float reflectionHeight);
void DrawTexture(CTextureRef texture, SRectF rect);
void DrawTexture(CTextureRef texture, SRectF rect, SColorF color);
void DrawTexture(CTextureRef texture, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false);
void DrawTexture(CTextureRef textureRef, SRectF bounds, EAspect aspect);
void DrawTexture(CTextureRef textureRef, SRectF bounds, EAspect aspect, SColorF color);
void DrawTextureReflection(CTextureRef texture, SRectF rect, SColorF color, float reflectionSpace, float reflectionHeight);
CTexture AddTexture(string fileName);
void RemoveTexture(ref CTexture texture);
CTextureRef AddTexture(string fileName);
void RemoveTexture(ref CTextureRef texture);
void DrawColor(SColorF color, SRectF rect);
void DrawColorReflection(SColorF color, SRectF rect, float space, float height);
void DrawRect(SColorF color, SRectF rect);
void DrawRectReflection(SColorF color, SRectF rect, float space, float height);
}
public interface IGraphics
@@ -175,15 +176,11 @@ namespace VocaluxeLib
public interface IFonts
{
void SetFont(string fontName);
void SetStyle(EStyle fontStyle);
RectangleF GetTextBounds(CText text);
RectangleF GetTextBounds(CText text, float textHeight);
void DrawText(string text, float textHeight, float x, float y, float z, SColorF color);
void DrawTextReflection(string text, float textHeight, float x, float y, float z, SColorF color, float reflectionSpace, float reflectionHeight);
void DrawText(string text, float textHeight, float x, float y, float z, SColorF color, float begin, float end);
void DrawText(string text, CFont font, float x, float y, float z, SColorF color);
void DrawTextReflection(string text, CFont font, float x, float y, float z, SColorF color, float reflectionSpace, float reflectionHeight);
void DrawText(string text, CFont font, float x, float y, float z, SColorF color, float begin, float end);
}
public interface ILanguage
@@ -226,7 +223,7 @@ namespace VocaluxeLib
CProfile[] GetProfiles();
EGameDifficulty GetDifficulty(int profileID);
string GetPlayerName(int profileID, int playerNum = 0);
CTexture GetAvatar(int profileID);
CTextureRef GetAvatar(int profileID);
CAvatar GetAvatarByFilename(string fileName);
bool IsProfileIDValid(int profileID);
bool IsGuest(int profileID);
@@ -267,7 +264,7 @@ namespace VocaluxeLib
{
int Load(string videoFileName);
bool Skip(int streamID, float startPosition, float videoGap);
bool GetFrame(int streamID, ref CTexture videoTexture, float time, out float videoTime);
bool GetFrame(int streamID, ref CTextureRef videoTexture, float time, out float videoTime);
bool IsFinished(int streamID);
bool Close(int streamID);
void SetLoop(int streamID, bool loop = true);
@@ -292,12 +289,12 @@ namespace VocaluxeLib
public interface ICover
{
CTexture GetNoCover();
CTextureRef GetNoCover();
}
public interface IDataBase
{
bool GetCover(string fileName, ref CTexture texture, int coverSize);
bool GetCover(string fileName, ref CTextureRef texture, int coverSize);
bool GetDataBaseSongInfos(string artist, string title, out int numPlayed, out DateTime dateAdded, out int highscoreID);
}
@@ -336,10 +333,9 @@ namespace VocaluxeLib
void Load(CSong song, float start = 0f);
void Stop();
void TogglePause();
CTexture GetCover();
CTexture GetVideoTexture();
CTextureRef GetCover();
CTextureRef GetVideoTexture();
bool IsPlaying();
float GetLength();
}
}
+44 -67
View File
@@ -16,12 +16,12 @@
#endregion
using System;
using System.Drawing;
using System.Xml;
using System.Xml.Serialization;
using System.Diagnostics;
using System.Collections.Generic;
using VocaluxeLib.Draw;
using VocaluxeLib.Xml;
namespace VocaluxeLib.Menu
{
@@ -37,16 +37,11 @@ namespace VocaluxeLib.Menu
[XmlType("Background")]
public struct SThemeBackground
{
[XmlAttributeAttribute(AttributeName = "Name")]
public string Name;
[XmlElement("Type")]
public EBackgroundTypes Type;
[XmlArray]
public List<string> SlideShowTextures;
[XmlElement("Video")]
public string VideoName;
[XmlElement("Skin")]
public string TextureName;
[XmlAttribute(AttributeName = "Name")] public string Name;
[XmlElement("Type")] public EBackgroundTypes Type;
[XmlArray] public List<string> SlideShowTextures;
[XmlElement("Video")] public string VideoName;
[XmlElement("Skin")] public string TextureName;
public SThemeColor Color;
}
@@ -58,7 +53,7 @@ namespace VocaluxeLib.Menu
private int _SlideShowCurrent;
private readonly Stopwatch _SlideShowTimer = new Stopwatch();
private readonly List<CTexture> _SlideShowTextures = new List<CTexture>();
private readonly List<CTextureRef> _SlideShowTextures = new List<CTextureRef>();
public SColorF Color;
public bool ThemeLoaded
@@ -149,36 +144,31 @@ namespace VocaluxeLib.Menu
CBase.Theme.SkinVideoPause(_Theme.VideoName, _PartyModeID);
}
public bool Draw()
public void Draw()
{
bool ok = false;
if (_Theme.Type == EBackgroundTypes.Video && CBase.Config.GetVideoBackgrounds() == EOffOn.TR_CONFIG_ON &&
CBase.Config.GetVideosToBackground() == EOffOn.TR_CONFIG_ON && CBase.BackgroundMusic.IsPlaying() && CBase.BackgroundMusic.SongHasVideo() &&
CBase.BackgroundMusic.VideoEnabled() && !CBase.BackgroundMusic.IsDisabled())
if (_Theme.Type == EBackgroundTypes.Video && CBase.Config.GetVideoBackgrounds() == EOffOn.TR_CONFIG_ON)
{
Pause();
ok = _DrawBackgroundMusicVideo();
if (CBase.Config.GetVideosToBackground() == EOffOn.TR_CONFIG_ON && CBase.BackgroundMusic.IsPlaying() && CBase.BackgroundMusic.SongHasVideo() &&
CBase.BackgroundMusic.VideoEnabled())
{
Pause();
ok = _DrawBackgroundMusicVideo();
}
else
{
Resume();
ok = _DrawVideo();
}
}
else if (_Theme.Type == EBackgroundTypes.Video && CBase.Config.GetVideoBackgrounds() == EOffOn.TR_CONFIG_ON)
{
Resume();
ok = _DrawVideo();
}
if (_Theme.Type == EBackgroundTypes.SlideShow && _Theme.SlideShowTextures.Count > 0)
else if (_Theme.Type == EBackgroundTypes.SlideShow && _Theme.SlideShowTextures.Count > 0)
ok = _DrawSlideShow();
if (!String.IsNullOrEmpty(_Theme.TextureName) &&
(_Theme.Type == EBackgroundTypes.Texture ||
(_Theme.Type == EBackgroundTypes.Video && CBase.Config.GetVideoBackgrounds() == EOffOn.TR_CONFIG_OFF)))
if (!String.IsNullOrEmpty(_Theme.TextureName) && (_Theme.Type == EBackgroundTypes.Texture || !ok))
ok = _DrawTexture();
if (_Theme.Type == EBackgroundTypes.Color || _Theme.Type == EBackgroundTypes.Texture && !ok ||
(_Theme.Type == EBackgroundTypes.Video && CBase.Config.GetVideoBackgrounds() == EOffOn.TR_CONFIG_OFF && !ok))
if (_Theme.Type == EBackgroundTypes.Color || !ok)
_DrawColor();
return true;
}
public void UnloadTextures()
@@ -200,7 +190,7 @@ namespace VocaluxeLib.Menu
_Theme.Type = EBackgroundTypes.SlideShow;
if (!String.IsNullOrEmpty(image))
{
CTexture texture = CBase.Drawing.AddTexture(image);
CTextureRef texture = CBase.Drawing.AddTexture(image);
if (texture != null)
_SlideShowTextures.Add(texture);
}
@@ -208,9 +198,9 @@ namespace VocaluxeLib.Menu
public void RemoveSlideShowTextures()
{
foreach (CTexture tex in _SlideShowTextures)
foreach (CTextureRef tex in _SlideShowTextures)
{
CTexture texture = tex;
CTextureRef texture = tex;
CBase.Drawing.RemoveTexture(ref texture);
}
_SlideShowTextures.Clear();
@@ -229,23 +219,22 @@ namespace VocaluxeLib.Menu
#endregion public
#region internal
private static SRectF _GetDrawRect()
{
return new SRectF(0f, 0f, CBase.Settings.GetRenderW(), CBase.Settings.GetRenderH(), CBase.Settings.GetZFar() / 4);
}
private void _DrawColor()
{
var bounds = new SRectF(0f, 0f, CBase.Settings.GetRenderW(), CBase.Settings.GetRenderH(), CBase.Settings.GetZFar() / 4);
CBase.Drawing.DrawColor(Color, bounds);
CBase.Drawing.DrawRect(Color, _GetDrawRect());
}
private bool _DrawTexture()
{
CTexture texture = CBase.Theme.GetSkinTexture(_Theme.TextureName, _PartyModeID);
CTextureRef texture = CBase.Theme.GetSkinTexture(_Theme.TextureName, _PartyModeID);
if (texture != null)
{
var bounds = new RectangleF(0f, 0f, CBase.Settings.GetRenderW(), CBase.Settings.GetRenderH());
RectangleF rect;
CHelper.SetRect(bounds, out rect, texture.OrigAspect, EAspect.Crop);
CBase.Drawing.DrawTexture(texture, new SRectF(rect.X, rect.Y, rect.Width, rect.Height, CBase.Settings.GetZFar() / 4));
CBase.Drawing.DrawTexture(texture, _GetDrawRect(), EAspect.Crop);
return true;
}
return false;
@@ -266,20 +255,16 @@ namespace VocaluxeLib.Menu
_SlideShowTimer.Restart();
if (_SlideShowCurrent + 1 < _SlideShowTextures.Count)
_SlideShowCurrent++;
else if (_SlideShowCurrent != 0)
else
_SlideShowCurrent = 0;
}
CTexture texture = _SlideShowTextures[_SlideShowCurrent];
CTextureRef texture = _SlideShowTextures[_SlideShowCurrent];
if (texture == null)
return false;
var bounds = new RectangleF(0f, 0f, CBase.Settings.GetRenderW(), CBase.Settings.GetRenderH());
RectangleF rect;
CHelper.SetRect(bounds, out rect, texture.OrigAspect, EAspect.Crop);
CBase.Drawing.DrawTexture(texture, new SRectF(rect.X, rect.Y, rect.Width, rect.Height, CBase.Settings.GetZFar() / 4));
CBase.Drawing.DrawTexture(texture, _GetDrawRect(), EAspect.Crop);
if (_SlideShowTimer.ElapsedMilliseconds >= CBase.Settings.GetSlideShowImageTime())
{
@@ -292,9 +277,9 @@ namespace VocaluxeLib.Menu
if (texture != null)
{
float alpha = (_SlideShowTimer.ElapsedMilliseconds - CBase.Settings.GetSlideShowImageTime()) / CBase.Settings.GetSlideShowFadeTime();
CHelper.SetRect(bounds, out rect, texture.OrigAspect, EAspect.Crop);
CBase.Drawing.DrawTexture(texture, new SRectF(rect.X, rect.Y, rect.Width, rect.Height, (CBase.Settings.GetZFar() / 4) - 1), new SColorF(1, 1, 1, alpha));
SColorF color = texture.Color;
color.A = (_SlideShowTimer.ElapsedMilliseconds - CBase.Settings.GetSlideShowImageTime()) / CBase.Settings.GetSlideShowFadeTime();
CBase.Drawing.DrawTexture(texture, _GetDrawRect(), EAspect.Crop, color);
}
}
@@ -305,14 +290,10 @@ namespace VocaluxeLib.Menu
private bool _DrawVideo()
{
CTexture videoTexture = CBase.Theme.GetSkinVideoTexture(_Theme.VideoName, _PartyModeID);
CTextureRef videoTexture = CBase.Theme.GetSkinVideoTexture(_Theme.VideoName, _PartyModeID);
if (videoTexture != null)
{
var bounds = new RectangleF(0f, 0f, CBase.Settings.GetRenderW(), CBase.Settings.GetRenderH());
RectangleF rect;
CHelper.SetRect(bounds, out rect, videoTexture.OrigAspect, EAspect.Crop);
CBase.Drawing.DrawTexture(videoTexture, new SRectF(rect.X, rect.Y, rect.Width, rect.Height, CBase.Settings.GetZFar() / 4));
CBase.Drawing.DrawTexture(videoTexture, _GetDrawRect(), EAspect.Crop);
return true;
}
return false;
@@ -320,14 +301,10 @@ namespace VocaluxeLib.Menu
private bool _DrawBackgroundMusicVideo()
{
CTexture videoTexture = CBase.BackgroundMusic.GetVideoTexture();
CTextureRef videoTexture = CBase.BackgroundMusic.GetVideoTexture();
if (videoTexture != null)
{
var bounds = new RectangleF(0f, 0f, CBase.Settings.GetRenderW(), CBase.Settings.GetRenderH());
RectangleF rect;
CHelper.SetRect(bounds, out rect, videoTexture.OrigAspect, EAspect.Crop);
CBase.Drawing.DrawTexture(videoTexture, new SRectF(rect.X, rect.Y, rect.Width, rect.Height, CBase.Settings.GetZFar() / 4));
CBase.Drawing.DrawTexture(videoTexture, _GetDrawRect(), EAspect.Crop);
return true;
}
return false;
+16 -25
View File
@@ -19,33 +19,25 @@ using System;
using System.Xml;
using System.Xml.Serialization;
using VocaluxeLib.Draw;
using VocaluxeLib.Xml;
namespace VocaluxeLib.Menu
{
[XmlType("Button")]
public struct SThemeButton
{
[XmlAttributeAttribute(AttributeName = "Name")]
public string Name;
[XmlAttribute(AttributeName = "Name")] public string Name;
[XmlElement("Skin")]
public string TextureName;
[XmlElement("SkinSelected")]
public string SelTextureName;
[XmlElement("Skin")] public string TextureName;
[XmlElement("SkinSelected")] public string SelTextureName;
public SRectF Rect;
[XmlElement("Color")]
public SThemeColor Color;
[XmlElement("SelColor")]
public SThemeColor SelColor;
[XmlElement("Text")]
public SThemeText Text;
[XmlElement("SText")]
public SThemeText SText;
[XmlElement("Color")] public SThemeColor Color;
[XmlElement("SelColor")] public SThemeColor SelColor;
[XmlElement("Text")] public SThemeText Text;
[XmlElement("SText")] public SThemeText SText;
public bool STextSpecified;
[XmlElement("Reflection")]
public SReflection Reflection;
[XmlElement("SelReflection")]
public SReflection SelReflection;
[XmlElement("Reflection")] public SReflection Reflection;
[XmlElement("SelReflection")] public SReflection SelReflection;
}
public class CButton : IMenuElement
@@ -54,8 +46,8 @@ namespace VocaluxeLib.Menu
private bool _ThemeLoaded;
private readonly int _PartyModeID;
public CTexture Texture;
public CTexture SelTexture;
public CTextureRef Texture;
public CTextureRef SelTexture;
public SRectF Rect;
public SColorF Color;
public SColorF SelColor;
@@ -257,13 +249,12 @@ namespace VocaluxeLib.Menu
return _ThemeLoaded;
}
public void Draw(bool forceDraw = false)
{
if (!Visible && CBase.Settings.GetProgramState() != EProgramState.EditTheme && !forceDraw)
return;
CTexture texture;
CTextureRef texture;
if (!Selected && !Pressed || !_Enabled)
{
@@ -273,7 +264,7 @@ namespace VocaluxeLib.Menu
if (_Reflection)
{
CBase.Drawing.DrawTextureReflection(texture, Rect, Color, Rect, _ReflectionSpace, _ReflectionHeight);
CBase.Drawing.DrawTextureReflection(texture, Rect, Color, _ReflectionSpace, _ReflectionHeight);
Text.DrawRelative(Rect.X, Rect.Y, _ReflectionHeight, _ReflectionSpace, Rect.H);
}
else
@@ -287,7 +278,7 @@ namespace VocaluxeLib.Menu
if (_Reflection)
{
CBase.Drawing.DrawTextureReflection(texture, Rect, SelColor, Rect, _ReflectionSpace, _ReflectionHeight);
CBase.Drawing.DrawTextureReflection(texture, Rect, SelColor, _ReflectionSpace, _ReflectionHeight);
Text.DrawRelative(Rect.X, Rect.Y, _ReflectionHeight, _ReflectionSpace, Rect.H);
}
else
@@ -301,7 +292,7 @@ namespace VocaluxeLib.Menu
if (_Reflection)
{
CBase.Drawing.DrawTextureReflection(texture, Rect, SelColor, Rect, _ReflectionSpace, _ReflectionHeight);
CBase.Drawing.DrawTextureReflection(texture, Rect, SelColor, _ReflectionSpace, _ReflectionHeight);
_SelText.DrawRelative(Rect.X, Rect.Y, _ReflectionHeight, _ReflectionSpace, Rect.H);
}
else
+14 -23
View File
@@ -18,6 +18,7 @@
using System;
using System.Xml;
using System.Xml.Serialization;
using VocaluxeLib.Xml;
namespace VocaluxeLib.Menu
{
@@ -29,30 +30,20 @@ namespace VocaluxeLib.Menu
[XmlType("Equalizer")]
public struct SThemeEqualizer
{
[XmlAttributeAttribute(AttributeName = "Name")]
public string Name;
[XmlAttribute(AttributeName = "Name")] public string Name;
[XmlElement("Skin")]
public string TextureName;
[XmlElement("Skin")] public string TextureName;
[XmlElement("Rect")]
public SRectF Rect;
[XmlElement("Rect")] public SRectF Rect;
[XmlElement("NumBars")]
public int NumBars;
[XmlElement("Space")]
public float Space;
[XmlElement("Style")]
public EEqualizerStyle Style;
[XmlElement("DrawNegative")]
public EOffOn DrawNegative;
[XmlElement("NumBars")] public int NumBars;
[XmlElement("Space")] public float Space;
[XmlElement("Style")] public EEqualizerStyle Style;
[XmlElement("DrawNegative")] public EOffOn DrawNegative;
[XmlElement("Color")]
public SThemeColor Color;
[XmlElement("MaxColor")]
public SThemeColor MaxColor;
[XmlElement("Reflection")]
public SReflection Reflection;
[XmlElement("Color")] public SThemeColor Color;
[XmlElement("MaxColor")] public SThemeColor MaxColor;
[XmlElement("Reflection")] public SReflection Reflection;
}
public class CEqualizer : IMenuElement
@@ -249,10 +240,10 @@ namespace VocaluxeLib.Menu
if (i == _MaxBar)
color = MaxColor;
CBase.Drawing.DrawColor(color, bar);
CBase.Drawing.DrawRect(color, bar);
if (Reflection)
CBase.Drawing.DrawColorReflection(color, bar, ReflectionSpace, ReflectionHeight);
CBase.Drawing.DrawRectReflection(color, bar, ReflectionSpace, ReflectionHeight);
}
}
@@ -273,7 +264,7 @@ namespace VocaluxeLib.Menu
Rect = _Theme.Rect;
Space = _Theme.Space;
Reflection = _Theme.Reflection.Enabled;
if(Reflection)
if (Reflection)
{
ReflectionHeight = _Theme.Reflection.Height;
ReflectionSpace = _Theme.Reflection.Space;
+10 -16
View File
@@ -19,22 +19,19 @@ using System;
using System.Xml;
using System.Xml.Serialization;
using VocaluxeLib.Songs;
using VocaluxeLib.Xml;
namespace VocaluxeLib.Menu
{
[XmlType("Lyric")]
public struct SThemeLyrics
{
[XmlAttributeAttribute(AttributeName = "Name")]
public string Name;
[XmlAttribute(AttributeName = "Name")] public string Name;
[XmlElement("Rect")]
public SRectF Rect;
[XmlElement("Rect")] public SRectF Rect;
[XmlElement("Color")]
public SThemeColor Color;
[XmlElement("SColor")]
public SThemeColor SColor;
[XmlElement("Color")] public SThemeColor Color;
[XmlElement("SColor")] public SThemeColor SColor;
}
public class CLyric : IMenuElement
@@ -192,10 +189,7 @@ namespace VocaluxeLib.Menu
private void _SetText(CSongNote note)
{
_Text.Text = note.Text;
_Text.Style = EStyle.Bold;
if (note.Type == ENoteType.Freestyle)
_Text.Style = EStyle.BoldItalic;
_Text.Font.Style = (note.Type == ENoteType.Freestyle) ? EStyle.BoldItalic : EStyle.Bold;
}
public void Clear()
@@ -337,11 +331,11 @@ namespace VocaluxeLib.Menu
p = 1f - p;
float ty = _Text.Y;
float th = _Text.Height;
float th = _Text.Font.Height;
float tz = _Text.Z;
SRectF normalRect = _Text.Rect;
_Text.Height += _Text.Height * p * 0.4f;
_Text.Font.Height *= 1f + p * 0.4f;
_Text.X -= (_Text.Rect.W - normalRect.W) / 2f;
_Text.Y -= (_Text.Rect.H - normalRect.H) / 2f;
_Text.Z -= 0.1f;
@@ -351,7 +345,7 @@ namespace VocaluxeLib.Menu
_Text.Draw();
_Text.Y = ty;
_Text.Height = th;
_Text.Font.Height = th;
_Text.Z = tz;
}
}
@@ -443,7 +437,7 @@ namespace VocaluxeLib.Menu
else
{
float y = _Text.Y;
_Text.Y -= _Text.Height * 0.1f * p;
_Text.Y -= _Text.Font.Height * 0.1f * p;
_Text.Draw();
_Text.Y = y;
}
+3 -2
View File
@@ -25,6 +25,7 @@ using System.Xml.Serialization;
using VocaluxeLib.Draw;
using VocaluxeLib.Menu.SingNotes;
using VocaluxeLib.Menu.SongMenu;
using VocaluxeLib.Xml;
namespace VocaluxeLib.Menu
{
@@ -587,7 +588,7 @@ namespace VocaluxeLib.Menu
return new CStatic(oldStatic);
}
public CStatic GetNewStatic(CTexture texture, SColorF color, SRectF rect)
public CStatic GetNewStatic(CTextureRef texture, SColorF color, SRectF rect)
{
return new CStatic(_PartyModeID, texture, color, rect);
}
@@ -632,7 +633,7 @@ namespace VocaluxeLib.Menu
return new CPlaylist(_PartyModeID);
}
public CParticleEffect GetNewParticleEffect(int maxNumber, SColorF color, SRectF area, CTexture texture, float size, EParticleType type)
public CParticleEffect GetNewParticleEffect(int maxNumber, SColorF color, SRectF area, CTextureRef texture, float size, EParticleType type)
{
return new CParticleEffect(_PartyModeID, maxNumber, color, area, texture, size, type);
}
+1 -1
View File
@@ -683,7 +683,7 @@ namespace VocaluxeLib.Menu
for (int i = 0; i < _TeamList[_CurrentTeam].Count; i++)
{
string name = CBase.Profiles.GetPlayerName(_TeamList[_CurrentTeam][i]);
CTexture avatar = CBase.Profiles.GetAvatar(_TeamList[_CurrentTeam][i]);
CTextureRef avatar = CBase.Profiles.GetAvatar(_TeamList[_CurrentTeam][i]);
_SelectSlides[_SelectSlidePlayer].AddValue(name, avatar);
}
for (int i = _TeamList[_CurrentTeam].Count; i < _NumPlayerTeams[_CurrentTeam]; i++)
+26 -42
View File
@@ -22,56 +22,39 @@ using System.Xml;
using System.Xml.Serialization;
using VocaluxeLib.Draw;
using VocaluxeLib.Profile;
using VocaluxeLib.Xml;
namespace VocaluxeLib.Menu
{
[XmlType("NameSelection")]
public struct SThemeNameSelection
{
[XmlAttributeAttribute(AttributeName = "Name")]
public string Name;
[XmlElement("Rect")]
public SRectF Rect;
[XmlElement("SkinEmptyTile")]
public string TextureEmptyTileName;
[XmlElement("ColorEmptyTile")]
public SThemeColor ColorEmptyTile;
[XmlElement("SkinTileSelected")]
public string TextureTileSelectedName;
[XmlElement("Tiles")]
public SThemeNameSelectionTiles Tiles;
[XmlAttribute(AttributeName = "Name")] public string Name;
[XmlElement("Rect")] public SRectF Rect;
[XmlElement("SkinEmptyTile")] public string TextureEmptyTileName;
[XmlElement("ColorEmptyTile")] public SThemeColor ColorEmptyTile;
[XmlElement("SkinTileSelected")] public string TextureTileSelectedName;
[XmlElement("Tiles")] public SThemeNameSelectionTiles Tiles;
}
public struct SThemeNameSelectionTiles
{
[XmlElement("W")]
public int W;
[XmlElement("H")]
public int H;
[XmlElement("NumW")]
public int NumW;
[XmlElement("NumH")]
public int NumH;
[XmlElement("SpaceW")]
public float SpaceW;
[XmlElement("SpaceH")]
public float SpaceH;
[XmlElement("Name")]
public SThemeNameSelectionName Name;
[XmlElement("W")] public int W;
[XmlElement("H")] public int H;
[XmlElement("NumW")] public int NumW;
[XmlElement("NumH")] public int NumH;
[XmlElement("SpaceW")] public float SpaceW;
[XmlElement("SpaceH")] public float SpaceH;
[XmlElement("Name")] public SThemeNameSelectionName Name;
}
public struct SThemeNameSelectionName
{
[XmlElement("Space")]
public float Space;
[XmlElement("H")]
public float Height;
[XmlElement("Font")]
public string Font;
[XmlElement("Style")]
public EStyle Style;
[XmlElement("Color")]
public SThemeColor Color;
[XmlElement("Space")] public float Space;
[XmlElement("H")] public float Height;
[XmlElement("Font")] public string Font;
[XmlElement("Style")] public EStyle Style;
[XmlElement("Color")] public SThemeColor Color;
}
public class CNameSelection : IMenuElement
@@ -110,16 +93,15 @@ namespace VocaluxeLib.Menu
public SRectF Rect;
private readonly List<CTile> _Tiles;
private CTexture _TextureEmptyTile;
private CTexture _TextureTileSelected;
public CTexture TextureEmptyTile
private CTextureRef _TextureEmptyTile;
private CTextureRef _TextureTileSelected;
public CTextureRef TextureEmptyTile
{
get { return _TextureEmptyTile; }
}
public SColorF ColorEmptyTile;
public int Offset;
private int _ActualSelection = -1;
public int Selection = -1;
@@ -517,9 +499,11 @@ namespace VocaluxeLib.Menu
{
for (int j = 0; j < _Theme.Tiles.NumW; j++)
{
var rect = new SRectF(Rect.X + j * (_Theme.Tiles.W + _Theme.Tiles.SpaceW), Rect.Y + i * (_Theme.Tiles.H + _Theme.Tiles.SpaceH), _Theme.Tiles.W, _Theme.Tiles.H, Rect.Z);
var rect = new SRectF(Rect.X + j * (_Theme.Tiles.W + _Theme.Tiles.SpaceW), Rect.Y + i * (_Theme.Tiles.H + _Theme.Tiles.SpaceH), _Theme.Tiles.W, _Theme.Tiles.H,
Rect.Z);
var tileStatic = new CStatic(_PartyModeID, _TextureEmptyTile, ColorEmptyTile, rect) {Aspect = EAspect.Crop};
var tileText = new CText(rect.X + rect.W / 2, rect.Y + rect.H + _Theme.Tiles.Name.Space, rect.Z, _Theme.Tiles.Name.Height, rect.W, EAlignment.Center, _Theme.Tiles.Name.Style,
var tileText = new CText(rect.X + rect.W / 2, rect.Y + rect.H + _Theme.Tiles.Name.Space, rect.Z, _Theme.Tiles.Name.Height, rect.W, EAlignment.Center,
_Theme.Tiles.Name.Style,
_Theme.Tiles.Name.Font, _Theme.Tiles.Name.Color.Color, "");
_Tiles.Add(new CTile(tileStatic, tileText, -1));
}
+12 -20
View File
@@ -21,27 +21,21 @@ using System.Diagnostics;
using System.Xml;
using System.Xml.Serialization;
using VocaluxeLib.Draw;
using VocaluxeLib.Xml;
namespace VocaluxeLib.Menu
{
[XmlType("ParticleEffect")]
public struct SThemeParticleEffect
{
[XmlAttributeAttribute(AttributeName = "Name")]
public string Name;
[XmlAttribute(AttributeName = "Name")] public string Name;
[XmlElement("Skin")]
public string TextureName;
[XmlElement("Rect")]
public SRectF Rect;
[XmlElement("Color")]
public SThemeColor Color;
[XmlElement("Type")]
public EParticleType Type;
[XmlElement("Size")]
public float Size;
[XmlElement("MaxNumber")]
public int MaxNumber;
[XmlElement("Skin")] public string TextureName;
[XmlElement("Rect")] public SRectF Rect;
[XmlElement("Color")] public SThemeColor Color;
[XmlElement("Type")] public EParticleType Type;
[XmlElement("Size")] public float Size;
[XmlElement("MaxNumber")] public int MaxNumber;
}
public enum EParticleType
@@ -58,7 +52,7 @@ namespace VocaluxeLib.Menu
#region private vars
private readonly int _PartyModeID;
private readonly string _TextureName;
private readonly CTexture _Texture;
private readonly CTextureRef _Texture;
private SRectF _Rect;
private float _Size;
private SColorF _Color;
@@ -141,7 +135,7 @@ namespace VocaluxeLib.Menu
_Rotation = (float)(CBase.Game.GetRandomDouble() * 360.0);
}
public CParticle(int partyModeID, CTexture texture, SColorF color, float x, float y, float size, float maxage, float z, float vx, float vy, float vr, float vsize,
public CParticle(int partyModeID, CTextureRef texture, SColorF color, float x, float y, float size, float maxage, float z, float vx, float vy, float vr, float vsize,
EParticleType type)
{
_PartyModeID = partyModeID;
@@ -159,8 +153,6 @@ namespace VocaluxeLib.Menu
_MaxAge = maxage;
_Rotation = (float)(CBase.Game.GetRandomDouble() * 360.0);
}
#endregion Constructors
public void Update()
@@ -316,7 +308,7 @@ namespace VocaluxeLib.Menu
private SThemeParticleEffect _Theme;
private bool _ThemeLoaded;
public CTexture Texture;
public CTextureRef Texture;
public SColorF Color;
public SRectF Rect;
@@ -370,7 +362,7 @@ namespace VocaluxeLib.Menu
Visible = true;
}
public CParticleEffect(int partyModeID, int maxNumber, SColorF color, SRectF rect, CTexture texture, float size, EParticleType type)
public CParticleEffect(int partyModeID, int maxNumber, SColorF color, SRectF rect, CTextureRef texture, float size, EParticleType type)
{
_PartyModeID = partyModeID;
_Theme = new SThemeParticleEffect();
+26 -42
View File
@@ -21,6 +21,7 @@ using System.Windows.Forms;
using System.Xml;
using System.Xml.Serialization;
using VocaluxeLib.Songs;
using VocaluxeLib.Xml;
namespace VocaluxeLib.Menu
{
@@ -57,48 +58,31 @@ namespace VocaluxeLib.Menu
[XmlType("Playlist")]
public struct SThemePlaylist
{
[XmlAttributeAttribute(AttributeName = "Name")]
public string Name;
[XmlAttribute(AttributeName = "Name")] public string Name;
[XmlElement("Rect")]
public SRectF Rect;
[XmlElement("Rect")] public SRectF Rect;
[XmlElement("EntryHeight")]
public float EntryHeight;
[XmlElement("EntryHeight")] public float EntryHeight;
[XmlElement("SkinBackground")]
public string TextureBackgroundName;
[XmlElement("SkinBackgroundSelected")]
public string SelTextureBackgroundName;
[XmlElement("SkinBackground")] public string TextureBackgroundName;
[XmlElement("SkinBackgroundSelected")] public string SelTextureBackgroundName;
[XmlElement("ColorBackground")]
public SThemeColor ColorBackground;
[XmlElement("SColorBackground")]
public SThemeColor SelColorBackground;
[XmlElement("ColorBackground")] public SThemeColor ColorBackground;
[XmlElement("SColorBackground")] public SThemeColor SelColorBackground;
[XmlElement("Text1")]
public SThemeText SText1;
[XmlElement("Text1")] public SThemeText SText1;
[XmlElement("StaticCover")]
public SThemeStatic SStaticCover;
[XmlElement("StaticPlaylistHeader")]
public SThemeStatic SStaticPlaylistHeader;
[XmlElement("StaticPlaylistFooter")]
public SThemeStatic SStaticPlaylistFooter;
[XmlElement("StaticCover")] public SThemeStatic SStaticCover;
[XmlElement("StaticPlaylistHeader")] public SThemeStatic SStaticPlaylistHeader;
[XmlElement("StaticPlaylistFooter")] public SThemeStatic SStaticPlaylistFooter;
[XmlElement("ButtonPlaylistName")]
public SThemeButton SButtonPlaylistName;
[XmlElement("ButtonPlaylistClose")]
public SThemeButton SButtonPlaylistClose;
[XmlElement("ButtonPlaylistSave")]
public SThemeButton SButtonPlaylistSave;
[XmlElement("ButtonPlaylistDelete")]
public SThemeButton SButtonPlaylistDelete;
[XmlElement("ButtonPlaylistSing")]
public SThemeButton SButtonPlaylistSing;
[XmlElement("ButtonPlaylistName")] public SThemeButton SButtonPlaylistName;
[XmlElement("ButtonPlaylistClose")] public SThemeButton SButtonPlaylistClose;
[XmlElement("ButtonPlaylistSave")] public SThemeButton SButtonPlaylistSave;
[XmlElement("ButtonPlaylistDelete")] public SThemeButton SButtonPlaylistDelete;
[XmlElement("ButtonPlaylistSing")] public SThemeButton SButtonPlaylistSing;
[XmlElement("SelectSlideGameMode")]
public SThemeSelectSlide SSelectSlideGameMode;
[XmlElement("SelectSlideGameMode")] public SThemeSelectSlide SSelectSlideGameMode;
}
public class CPlaylist : IMenuElement
@@ -187,7 +171,7 @@ namespace VocaluxeLib.Menu
public SColorF BackgroundSelColor;
public CButton ButtonPlaylistName;
public CButton ButtonPlaylistClose;
public CButton ButtonPlaylistClose;
public CButton ButtonPlaylistSave;
public CButton ButtonPlaylistDelete;
public CButton ButtonPlaylistSing;
@@ -353,7 +337,7 @@ namespace VocaluxeLib.Menu
_ThemeLoaded &= ButtonPlaylistSave.LoadTheme(item, "ButtonPlaylistSave", xmlReader, skinIndex);
_ThemeLoaded &= ButtonPlaylistDelete.LoadTheme(item, "ButtonPlaylistDelete", xmlReader, skinIndex);
_ThemeLoaded &=SelectSlideGameMode.LoadTheme(item, "SelectSlideGameMode", xmlReader, skinIndex);
_ThemeLoaded &= SelectSlideGameMode.LoadTheme(item, "SelectSlideGameMode", xmlReader, skinIndex);
_ThemeLoaded &= xmlReader.TryGetFloatValue(item + "/EntryHeight", ref _Theme.EntryHeight);
if (_ThemeLoaded)
@@ -366,11 +350,11 @@ namespace VocaluxeLib.Menu
_Theme.SStaticCover = StaticCover.GetTheme();
_Theme.SStaticPlaylistFooter = StaticPlaylistFooter.GetTheme();
_Theme.SStaticPlaylistHeader = StaticPlaylistHeader.GetTheme();
_Theme.SButtonPlaylistName =ButtonPlaylistName.GetTheme();
_Theme.SButtonPlaylistSing =ButtonPlaylistSing.GetTheme();
_Theme.SButtonPlaylistClose =ButtonPlaylistClose.GetTheme();
_Theme.SButtonPlaylistSave =ButtonPlaylistSave.GetTheme();
_Theme.SButtonPlaylistDelete =ButtonPlaylistDelete.GetTheme();
_Theme.SButtonPlaylistName = ButtonPlaylistName.GetTheme();
_Theme.SButtonPlaylistSing = ButtonPlaylistSing.GetTheme();
_Theme.SButtonPlaylistClose = ButtonPlaylistClose.GetTheme();
_Theme.SButtonPlaylistSave = ButtonPlaylistSave.GetTheme();
_Theme.SButtonPlaylistDelete = ButtonPlaylistDelete.GetTheme();
LoadTextures();
}
@@ -405,7 +389,7 @@ namespace VocaluxeLib.Menu
public bool IsMouseOver(SMouseEvent mouseEvent)
{
return CHelper.IsInBounds(CompleteRect, mouseEvent.X, mouseEvent.Y) || _Interactions.IsMouseOver(mouseEvent);
return CHelper.IsInBounds(CompleteRect, mouseEvent) || _Interactions.IsMouseOver(mouseEvent);
}
public void UnloadTextures()
+5 -7
View File
@@ -19,6 +19,7 @@ using System;
using System.Xml;
using System.Xml.Serialization;
using VocaluxeLib.Draw;
using VocaluxeLib.Xml;
namespace VocaluxeLib.Menu
{
@@ -33,12 +34,9 @@ namespace VocaluxeLib.Menu
[XmlType("ScreenSetting")]
public struct SScreenSetting
{
[XmlAttributeAttribute(AttributeName = "Name")]
public string Name;
[XmlElement("Value")]
public string Value;
[XmlElement("Type")]
public ESettingType Type;
[XmlAttribute(AttributeName = "Name")] public string Name;
[XmlElement("Value")] public string Value;
[XmlElement("Type")] public ESettingType Type;
}
// ReSharper disable ClassNeverInstantiated.Global
@@ -131,7 +129,7 @@ namespace VocaluxeLib.Menu
}
}
private CTexture _GetTextureValue(string value)
private CTextureRef _GetTextureValue(string value)
{
return CBase.Theme.GetSkinTexture(value, _PartyModeID);
}
+42 -68
View File
@@ -18,75 +18,50 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Xml;
using System.Xml.Serialization;
using VocaluxeLib.Draw;
using VocaluxeLib.Xml;
namespace VocaluxeLib.Menu
{
[XmlType("SelectSlide")]
public struct SThemeSelectSlide
{
[XmlAttributeAttribute(AttributeName = "Name")]
public string Name;
[XmlAttribute(AttributeName = "Name")] public string Name;
[XmlElement("Skin")]
public string TextureName;
[XmlElement("SkinArrowLeft")]
public string TextureArrowLeftName;
[XmlElement("SkinArrowRight")]
public string TextureArrowRightName;
[XmlElement("Skin")] public string TextureName;
[XmlElement("SkinArrowLeft")] public string TextureArrowLeftName;
[XmlElement("SkinArrowRight")] public string TextureArrowRightName;
[XmlElement("SkinSelected")]
public string SelTextureName;
[XmlElement("SkinArrowLeftSelected")]
public string SelTextureArrowLeftName;
[XmlElement("SkinArrowRightSelected")]
public string SelTextureArrowRightName;
[XmlElement("SkinSelected")] public string SelTextureName;
[XmlElement("SkinArrowLeftSelected")] public string SelTextureArrowLeftName;
[XmlElement("SkinArrowRightSelected")] public string SelTextureArrowRightName;
[XmlElement("SkinHighlighted")]
public string HighlightTextureName;
[XmlElement("SkinHighlighted")] public string HighlightTextureName;
[XmlElement("Rect")]
public SRectF Rect;
[XmlElement("RectArrowLeft")]
public SRectF RectArrowLeft;
[XmlElement("RectArrowRight")]
public SRectF RectArrowRight;
[XmlElement("Rect")] public SRectF Rect;
[XmlElement("RectArrowLeft")] public SRectF RectArrowLeft;
[XmlElement("RectArrowRight")] public SRectF RectArrowRight;
[XmlElement("Color")]
public SThemeColor Color;
[XmlElement("SColor")]
public SThemeColor SColor;
[XmlElement("HColor")]
public SThemeColor HColor;
[XmlElement("Color")] public SThemeColor Color;
[XmlElement("SColor")] public SThemeColor SColor;
[XmlElement("HColor")] public SThemeColor HColor;
[XmlElement("ArrowColor")]
public SThemeColor ArrowColor;
[XmlElement("ArrowSColor")]
public SThemeColor ArrowSColor;
[XmlElement("ArrowColor")] public SThemeColor ArrowColor;
[XmlElement("ArrowSColor")] public SThemeColor ArrowSColor;
[XmlElement("TextColor")]
public SThemeColor TextColor;
[XmlElement("TextSColor")]
public SThemeColor TextSColor;
[XmlElement("TextColor")] public SThemeColor TextColor;
[XmlElement("TextSColor")] public SThemeColor TextSColor;
[XmlElement("TextH")]
public float TextH;
[XmlElement("TextRelativeX")]
public float TextRelativeX;
[XmlElement("TextRelativeY")]
public float TextRelativeY;
[XmlElement("TextMaxW")]
public float TextMaxW;
[XmlElement("TextH")] public float TextH;
[XmlElement("TextRelativeX")] public float TextRelativeX;
[XmlElement("TextRelativeY")] public float TextRelativeY;
[XmlElement("TextMaxW")] public float TextMaxW;
[XmlElement("TextFont")]
public string TextFont;
[XmlElement("TextStyle")]
public EStyle TextStyle;
[XmlElement("TextFont")] public string TextFont;
[XmlElement("TextStyle")] public EStyle TextStyle;
[XmlElement("NumVisible")]
public int NumVisible;
[XmlElement("NumVisible")] public int NumVisible;
}
public class CSelectSlide : IMenuElement, ICloneable
@@ -154,7 +129,7 @@ namespace VocaluxeLib.Menu
private readonly List<string> _ValueNames;
private readonly List<int> _ValuePartyModeIDs;
private readonly List<CTexture> _Textures;
private readonly List<CTextureRef> _Textures;
private readonly List<int> _ValueIndexes;
private readonly List<SRectF> _ValueBounds = new List<SRectF>();
@@ -222,7 +197,7 @@ namespace VocaluxeLib.Menu
MaxW = 0f;
_Selected = false;
_Textures = new List<CTexture>();
_Textures = new List<CTextureRef>();
_ValueIndexes = new List<int>();
_ValueNames = new List<string>();
_ValuePartyModeIDs = new List<int>();
@@ -270,7 +245,7 @@ namespace VocaluxeLib.Menu
MaxW = slide.MaxW;
_Selected = slide._Selected;
_Textures = new List<CTexture>(slide._Textures);
_Textures = new List<CTextureRef>(slide._Textures);
_ValueIndexes = new List<int>(slide._ValueIndexes);
_ValueNames = new List<string>(slide._ValueNames);
_ValueBounds = new List<SRectF>(slide._ValueBounds);
@@ -288,7 +263,7 @@ namespace VocaluxeLib.Menu
_Theme = theme;
_Selected = false;
_Textures = new List<CTexture>();
_Textures = new List<CTextureRef>();
_ValueIndexes = new List<int>();
_ValueNames = new List<string>();
_ValuePartyModeIDs = new List<int>();
@@ -444,17 +419,17 @@ namespace VocaluxeLib.Menu
AddValue(value, null, _ValueIndexes.Count, partyModeID);
}
public void AddValue(string value, CTexture texture)
public void AddValue(string value, CTextureRef texture)
{
AddValue(value, texture, _ValueIndexes.Count, _PartyModeID);
}
private void _AddValue(string value, CTexture texture, int valueIndex)
private void _AddValue(string value, CTextureRef texture, int valueIndex)
{
AddValue(value, texture, valueIndex, _PartyModeID);
}
public void AddValue(string value, CTexture texture, int valueIndex, int partyModeID)
public void AddValue(string value, CTextureRef texture, int valueIndex, int partyModeID)
{
_ValueNames.Add(value);
_Textures.Add(texture);
@@ -475,7 +450,7 @@ namespace VocaluxeLib.Menu
_ValueBounds.Clear();
}
public void AddValues(string[] values, CTexture[] textures)
public void AddValues(string[] values, CTextureRef[] textures)
{
if (values.Length != textures.Length)
return;
@@ -499,7 +474,7 @@ namespace VocaluxeLib.Menu
RenameValue(Selection, newName);
}
public void RenameValue(int selection, string newName, CTexture newTexture = null)
public void RenameValue(int selection, string newName, CTextureRef newTexture = null)
{
if (selection < 0 && selection >= _ValueNames.Count)
return;
@@ -623,15 +598,15 @@ namespace VocaluxeLib.Menu
if (!Visible && CBase.Settings.GetProgramState() != EProgramState.EditTheme)
return;
CTexture texture = CBase.Theme.GetSkinTexture(_Theme.TextureName, _PartyModeID);
CTexture textureArrowLeft = CBase.Theme.GetSkinTexture(_Theme.TextureArrowLeftName, _PartyModeID);
CTexture textureArrowRight = CBase.Theme.GetSkinTexture(_Theme.TextureArrowRightName, _PartyModeID);
CTextureRef texture = CBase.Theme.GetSkinTexture(_Theme.TextureName, _PartyModeID);
CTextureRef textureArrowLeft = CBase.Theme.GetSkinTexture(_Theme.TextureArrowLeftName, _PartyModeID);
CTextureRef textureArrowRight = CBase.Theme.GetSkinTexture(_Theme.TextureArrowRightName, _PartyModeID);
CTexture selTexture = CBase.Theme.GetSkinTexture(_Theme.SelTextureName, _PartyModeID);
CTexture selTextureArrowLeft = CBase.Theme.GetSkinTexture(_Theme.SelTextureArrowLeftName, _PartyModeID);
CTexture selTextureArrowRight = CBase.Theme.GetSkinTexture(_Theme.SelTextureArrowRightName, _PartyModeID);
CTextureRef selTexture = CBase.Theme.GetSkinTexture(_Theme.SelTextureName, _PartyModeID);
CTextureRef selTextureArrowLeft = CBase.Theme.GetSkinTexture(_Theme.SelTextureArrowLeftName, _PartyModeID);
CTextureRef selTextureArrowRight = CBase.Theme.GetSkinTexture(_Theme.SelTextureArrowRightName, _PartyModeID);
CTexture highlightTexture = CBase.Theme.GetSkinTexture(_Theme.HighlightTextureName, _PartyModeID);
CTextureRef highlightTexture = CBase.Theme.GetSkinTexture(_Theme.HighlightTextureName, _PartyModeID);
if (Selected)
{
@@ -773,7 +748,6 @@ namespace VocaluxeLib.Menu
TextRelativeX = _Theme.TextRelativeX;
TextRelativeY = _Theme.TextRelativeY;
MaxW = _Theme.TextMaxW;
}
public void ReloadTextures()
+21 -24
View File
@@ -19,16 +19,15 @@ using System;
using System.Xml;
using System.Xml.Serialization;
using VocaluxeLib.Draw;
using VocaluxeLib.Xml;
namespace VocaluxeLib.Menu
{
[XmlType("Static")]
public struct SThemeStatic
{
[XmlAttributeAttribute(AttributeName = "Name")]
public string Name;
[XmlElement("Skin")]
public string TextureName;
[XmlAttribute(AttributeName = "Name")] public string Name;
[XmlElement("Skin")] public string TextureName;
public SThemeColor Color;
public SRectF Rect;
public SReflection Reflection;
@@ -51,8 +50,8 @@ namespace VocaluxeLib.Menu
get { return _ThemeLoaded; }
}
private CTexture _Texture;
public CTexture Texture
private CTextureRef _Texture;
public CTextureRef Texture
{
get { return _Texture ?? CBase.Theme.GetSkinTexture(_Theme.TextureName, _PartyModeID); }
@@ -73,10 +72,7 @@ namespace VocaluxeLib.Menu
public EAspect Aspect = EAspect.Stretch;
public CStatic()
{
}
public CStatic() {}
public CStatic(int partyModeID)
{
@@ -99,7 +95,7 @@ namespace VocaluxeLib.Menu
Visible = s.Visible;
}
public CStatic(int partyModeID, CTexture texture, SColorF color, SRectF rect)
public CStatic(int partyModeID, CTextureRef texture, SColorF color, SRectF rect)
{
_PartyModeID = partyModeID;
@@ -179,26 +175,27 @@ namespace VocaluxeLib.Menu
public void Draw(EAspect aspect, float scale = 1f, float zModify = 0f, bool forceDraw = false)
{
CTexture texture = Texture ?? new CTexture((int)Rect.W, (int)Rect.H);
SRectF bounds = Rect.Scale(scale);
SRectF rect;
if (aspect != EAspect.Stretch)
CHelper.SetRect(bounds, out rect, texture.OrigAspect, aspect);
else
rect = bounds;
rect.Z = Rect.Z + zModify;
CTextureRef texture = Texture;
SRectF rect = Rect.Scale(scale);
rect.Z += zModify;
if (texture != null)
rect = CHelper.FitInBounds(rect, texture.OrigAspect, aspect);
var color = new SColorF(Color.R, Color.G, Color.B, Color.A * Alpha);
if (Visible || forceDraw || (CBase.Settings.GetProgramState() == EProgramState.EditTheme))
{
CBase.Drawing.DrawTexture(texture, rect, color, bounds);
if (Reflection)
CBase.Drawing.DrawTextureReflection(texture, rect, color, bounds, ReflectionSpace, ReflectionHeight);
if (texture != null)
{
CBase.Drawing.DrawTexture(texture, rect, color);
if (Reflection)
CBase.Drawing.DrawTextureReflection(texture, rect, color, ReflectionSpace, ReflectionHeight);
}
else
CBase.Drawing.DrawRect(color, rect);
}
if (Selected && (CBase.Settings.GetProgramState() == EProgramState.EditTheme))
CBase.Drawing.DrawColor(new SColorF(1f, 1f, 1f, 0.5f), rect);
CBase.Drawing.DrawRect(new SColorF(1f, 1f, 1f, 0.5f), rect);
}
public void UnloadTextures() {}
+56 -101
View File
@@ -17,43 +17,32 @@
using System;
using System.Drawing;
using System.Xml;
using System.Xml.Serialization;
using VocaluxeLib.Xml;
namespace VocaluxeLib.Menu
{
[XmlType("Text")]
public struct SThemeText
{
[XmlAttributeAttribute(AttributeName = "Name")]
public string Name;
[XmlAttribute(AttributeName = "Name")] public string Name;
[XmlElement("X")]
public float X;
[XmlElement("Y")]
public float Y;
[XmlElement("Z")]
public float Z;
[XmlElement("H")]
public float Height;
[XmlElement("MaxW")]
public float MaxWidth;
[XmlElement("X")] public float X;
[XmlElement("Y")] public float Y;
[XmlElement("Z")] public float Z;
[XmlElement("H")] public float FontHeight;
[XmlElement("MaxW")] public float MaxWidth;
public SThemeColor Color;
public SThemeColor SColor; //for Buttons
[XmlElement("Align")]
public EAlignment Align;
[XmlElement("ResizeAlign")]
public EHAlignment ResizeAlign;
[XmlElement("Style")]
public EStyle Style;
[XmlElement("Font")]
public string Font;
[XmlElement("Text")]
public string Text;
[XmlElement("Align")] public EAlignment Align;
[XmlElement("ResizeAlign")] public EHAlignment ResizeAlign;
[XmlElement("Style")] public EStyle FontStyle;
[XmlElement("Font")] public string FontFamily;
[XmlElement("Text")] public string Text;
public SReflection Reflection;
}
public class CText : IMenuElement
public class CText : IMenuElement, IFontObserver
{
private SThemeText _Theme;
private bool _ThemeLoaded;
@@ -110,20 +99,6 @@ namespace VocaluxeLib.Menu
set { _Z = value; }
}
private float _Height;
public float Height
{
get { return _Height; }
set
{
if (Math.Abs(_Height - value) > 0.01)
{
_Height = value;
_PositionNeedsUpdate = true;
}
}
}
private float _MaxWidth;
public float MaxWidth
{
@@ -166,29 +141,17 @@ namespace VocaluxeLib.Menu
}
}
private EStyle _Style = EStyle.Normal;
public EStyle Style
{
get { return _Style; }
set
{
if (_Style != value)
{
_Style = value;
_PositionNeedsUpdate = true;
}
}
}
private string _Font = String.Empty;
public string Font
private CFont _Font = new CFont();
public CFont Font
{
get { return _Font; }
set
{
if (_Font != value)
if (!_Font.Equals(value))
{
_Font.RemoveObserver(this);
_Font = value;
_Font.AddObserver(this);
_PositionNeedsUpdate = true;
}
}
@@ -227,10 +190,16 @@ namespace VocaluxeLib.Menu
_Text = translation;
if (_EditMode)
_Text += "|";
//Reset height, it might have been reduced in _UpdatePosition
Font.Height = _Theme.FontHeight;
_PositionNeedsUpdate = true;
}
}
}
public string TranslatedText
{
get { return _Text; }
}
public int PartyModeID
{
@@ -274,7 +243,7 @@ namespace VocaluxeLib.Menu
{
_PartyModeID = partyModeID;
_TranslationID = _PartyModeID;
_Font = "Normal";
_Font.AddObserver(this);
}
public CText(CText text)
@@ -285,12 +254,10 @@ namespace VocaluxeLib.Menu
_X = text._X;
_Y = text._Y;
_Z = text._Z;
_Height = text._Height;
_MaxWidth = text._MaxWidth;
_Align = text._Align;
_ResizeAlign = text._ResizeAlign;
_Style = text._Style;
_Font = text._Font;
Font = text.Font; //Use setter to set observer
Color = new SColorF(text.Color);
SelColor = new SColorF(text.SelColor);
@@ -305,24 +272,23 @@ namespace VocaluxeLib.Menu
_EditMode = text._EditMode;
}
public CText(float x, float y, float z, float h, float mw, EAlignment align, EStyle style, string font, SColorF col, string text, int partyModeID = -1, float rheight = 0,
float rspace = 0)
public CText(float x, float y, float z, float h, float mw, EAlignment align, EStyle style, string fontFamily, SColorF col, string text, int partyModeID = -1,
float rheight = 0,
float rspace = 0) : this(partyModeID)
{
_Theme = new SThemeText();
_Theme = new SThemeText {FontFamily = fontFamily, FontStyle = style, FontHeight = h, Text = text};
_ThemeLoaded = false;
_ButtonText = false;
_PartyModeID = partyModeID;
_TranslationID = _PartyModeID;
X = x;
Y = y;
Z = z;
Height = h;
MaxWidth = mw;
Align = align;
ResizeAlign = EHAlignment.Center;
Style = style;
Font = font;
_Font.Name = fontFamily;
_Font.Style = style;
_Font.Height = h;
Color = col;
SelColor = new SColorF(col);
@@ -362,7 +328,6 @@ namespace VocaluxeLib.Menu
if (!buttonText)
_ThemeLoaded &= xmlReader.TryGetFloatValue(item + "/Z", ref _Z);
_ThemeLoaded &= xmlReader.TryGetFloatValue(item + "/H", ref _Height);
xmlReader.TryGetFloatValue(item + "/MaxW", ref _MaxWidth);
if (xmlReader.GetValue(item + "/Color", out _Theme.Color.Name, String.Empty))
@@ -389,8 +354,9 @@ namespace VocaluxeLib.Menu
_ThemeLoaded &= xmlReader.TryGetEnumValue(item + "/Align", ref _Align);
xmlReader.TryGetEnumValue(item + "/ResizeAlign", ref _ResizeAlign);
_ThemeLoaded &= xmlReader.TryGetEnumValue(item + "/Style", ref _Style);
_ThemeLoaded &= xmlReader.GetValue(item + "/Font", out _Font, "Normal");
_ThemeLoaded &= xmlReader.TryGetFloatValue(item + "/H", ref _Theme.FontHeight);
_ThemeLoaded &= xmlReader.TryGetEnumValue(item + "/Style", ref _Theme.FontStyle);
_ThemeLoaded &= xmlReader.GetValue(item + "/Font", out _Theme.FontFamily);
_ThemeLoaded &= xmlReader.GetValue(item + "/Text", out _Theme.Text, String.Empty);
@@ -407,15 +373,12 @@ namespace VocaluxeLib.Menu
_Theme.Name = elementName;
_Theme.Align = _Align;
_Theme.Color.Color = Color;
_Theme.Font = _Font;
_Theme.ResizeAlign = _ResizeAlign;
_Theme.SColor.Color = SelColor;
_Theme.Style = _Style;
_Theme.MaxWidth = _MaxWidth;
_Theme.X = _X;
_Theme.Y = _Y;
_Theme.Z = _Z;
_Theme.Height = _Height;
_ButtonText = buttonText;
_PositionNeedsUpdate = true;
@@ -425,7 +388,6 @@ namespace VocaluxeLib.Menu
return _ThemeLoaded;
}
public void Draw(bool forceDraw = false)
{
if (!forceDraw && !Visible && CBase.Settings.GetProgramState() != EProgramState.EditTheme)
@@ -434,30 +396,24 @@ namespace VocaluxeLib.Menu
// Update Text
Text = Text;
CBase.Fonts.SetFont(Font);
CBase.Fonts.SetStyle(Style);
SColorF currentColor = (Selected) ? SelColor : Color;
var color = new SColorF(currentColor.R, currentColor.G, currentColor.B, currentColor.A * Alpha);
CBase.Fonts.DrawText(_Text, Rect.H, Rect.X, Rect.Y, Z, color);
CBase.Fonts.DrawText(_Text, Font, Rect.X, Rect.Y, Z, color);
if (ReflectionHeight > 0)
CBase.Fonts.DrawTextReflection(_Text, Rect.H, Rect.X, Rect.Y, Z, color, ReflectionSpace, ReflectionHeight);
CBase.Fonts.DrawTextReflection(_Text, Font, Rect.X, Rect.Y, Z, color, ReflectionSpace, ReflectionHeight);
if (Selected && (CBase.Settings.GetProgramState() == EProgramState.EditTheme))
CBase.Drawing.DrawColor(new SColorF(0.5f, 1f, 0.5f, 0.5f), new SRectF(Rect.X, Rect.Y, Rect.W, Rect.H, Z));
CBase.Drawing.DrawRect(new SColorF(0.5f, 1f, 0.5f, 0.5f), new SRectF(Rect.X, Rect.Y, Rect.W, Rect.H, Z));
}
public void Draw(float begin, float end)
{
CBase.Fonts.SetFont(Font);
CBase.Fonts.SetStyle(Style);
SColorF currentColor = (Selected) ? SelColor : Color;
var color = new SColorF(currentColor.R, currentColor.G, currentColor.B, currentColor.A * Alpha);
CBase.Fonts.DrawText(Text, Rect.H, Rect.X, Rect.Y, Z, color, begin, end);
CBase.Fonts.DrawText(Text, Font, Rect.X, Rect.Y, Z, color, begin, end);
if (ReflectionHeight > 0)
{
@@ -465,7 +421,7 @@ namespace VocaluxeLib.Menu
}
if (Selected && (CBase.Settings.GetProgramState() == EProgramState.EditTheme))
CBase.Drawing.DrawColor(new SColorF(0.5f, 1f, 0.5f, 0.5f), new SRectF(X, Y, Rect.W, Rect.H, Z));
CBase.Drawing.DrawRect(new SColorF(0.5f, 1f, 0.5f, 0.5f), new SRectF(X, Y, Rect.W, Rect.H, Z));
}
public void DrawRelative(float rx, float ry, float reflectionHeight = 0f, float reflectionSpace = 0f, float rectHeight = 0f)
@@ -505,12 +461,10 @@ namespace VocaluxeLib.Menu
_X = _Theme.X;
_Y = _Theme.Y;
_Z = _Theme.Z;
_Height = _Theme.Height;
_MaxWidth = _Theme.MaxWidth;
_Align = _Theme.Align;
_ResizeAlign = _Theme.ResizeAlign;
_Style = _Theme.Style;
_Font = _Theme.Font;
Font = new CFont(_Theme.FontFamily, _Theme.FontStyle, _Theme.FontHeight);
if (_Theme.Reflection.Enabled)
{
@@ -541,17 +495,16 @@ namespace VocaluxeLib.Menu
X += stepX;
Y += stepY;
_Theme.X += stepX;
_Theme.Y += stepY;
_Theme.X = X;
_Theme.Y = Y;
}
public void ResizeElement(int stepW, int stepH)
{
Height += stepH;
if (Height <= 0)
Height = 1;
_Theme.Height = _Height;
_Theme.FontHeight += stepH;
if (_Theme.FontHeight <= 0)
_Theme.FontHeight = 1;
_Font.Height = _Theme.FontHeight;
}
#endregion ThemeEdit
@@ -560,10 +513,7 @@ namespace VocaluxeLib.Menu
if (_Text == "")
return;
CBase.Fonts.SetFont(Font);
CBase.Fonts.SetStyle(Style);
float h = Height;
float h = Font.Height;
float y = Y;
RectangleF bounds = CBase.Fonts.GetTextBounds(this);
@@ -584,8 +534,8 @@ namespace VocaluxeLib.Menu
y += step * 0.75f;
break;
}
bounds = CBase.Fonts.GetTextBounds(this, h);
Font.Height = h;
bounds = CBase.Fonts.GetTextBounds(this);
}
float x = X;
@@ -606,5 +556,10 @@ namespace VocaluxeLib.Menu
_PositionNeedsUpdate = false;
}
public void FontChanged()
{
_PositionNeedsUpdate = true;
}
}
}
+1
View File
@@ -16,6 +16,7 @@
#endregion
using System.Xml;
using VocaluxeLib.Xml;
namespace VocaluxeLib.Menu
{
+41 -56
View File
@@ -18,10 +18,10 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Xml;
using System.Xml.Serialization;
using VocaluxeLib.Draw;
using VocaluxeLib.Songs;
using VocaluxeLib.Xml;
namespace VocaluxeLib.Menu.SingNotes
{
@@ -42,42 +42,30 @@ namespace VocaluxeLib.Menu.SingNotes
}
[XmlType("Position")]
public struct SBarPosition
public struct SBarPosition
{
[XmlAttributeAttribute(AttributeName = "Name")]
public string Name;
[XmlAttribute(AttributeName = "Name")] public string Name;
public SRectF Rect;
}
[XmlType("SingBar")]
public struct SThemeSingBar
{
[XmlAttributeAttribute(AttributeName = "Name")]
public string Name;
[XmlAttribute(AttributeName = "Name")] public string Name;
[XmlElement("SkinLeft")]
public string SkinLeftName;
[XmlElement("SkinMiddle")]
public string SkinMiddleName;
[XmlElement("SkinRight")]
public string SkinRightName;
[XmlElement("SkinLeft")] public string SkinLeftName;
[XmlElement("SkinMiddle")] public string SkinMiddleName;
[XmlElement("SkinRight")] public string SkinRightName;
[XmlElement("SkinBackgroundLeft")]
public string SkinBackgroundLeftName;
[XmlElement("SkinBackgroundMiddle")]
public string SkinBackgroundMiddleName;
[XmlElement("SkinBackgroundRight")]
public string SkinBackgroundRightName;
[XmlElement("SkinBackgroundLeft")] public string SkinBackgroundLeftName;
[XmlElement("SkinBackgroundMiddle")] public string SkinBackgroundMiddleName;
[XmlElement("SkinBackgroundRight")] public string SkinBackgroundRightName;
[XmlElement("SkinGoldenStar")]
public string SkinGoldenStarName;
[XmlElement("SkinToneHelper")]
public string SkinToneHelperName;
[XmlElement("SkinPerfectNoteStart")]
public string SkinPerfectNoteStarName;
[XmlElement("SkinGoldenStar")] public string SkinGoldenStarName;
[XmlElement("SkinToneHelper")] public string SkinToneHelperName;
[XmlElement("SkinPerfectNoteStart")] public string SkinPerfectNoteStarName;
[XmlArray("BarPositions")]
public SBarPosition[] BarPos;
[XmlArray("BarPositions")] public SBarPosition[] BarPos;
}
public abstract class CSingNotes : IMenuElement
@@ -116,7 +104,7 @@ namespace VocaluxeLib.Menu.SingNotes
_PlayerNotes = new List<SPlayerNotes>();
_ActID = 0;
BarPos = new SRectF[CBase.Settings.GetMaxNumPlayer(), CBase.Settings.GetMaxNumPlayer()];
BarPos = new SRectF[CBase.Settings.GetMaxNumPlayer(),CBase.Settings.GetMaxNumPlayer()];
LoadTextures();
}
@@ -152,21 +140,18 @@ namespace VocaluxeLib.Menu.SingNotes
BarPos = new SRectF[CBase.Settings.GetMaxNumPlayer(),CBase.Settings.GetMaxNumPlayer()];
for (int numplayer = 0; numplayer < CBase.Settings.GetMaxNumPlayer(); numplayer++)
{
for (int player = 0; player < CBase.Settings.GetMaxNumPlayer(); player++)
for (int player = 0; player <= numplayer; player++)
{
if (player <= numplayer)
{
BarPos[player, numplayer] = new SRectF();
string target = "/BarPositions/P" + (player + 1) + "N" + (numplayer + 1);
_ThemeLoaded &= xmlReader.TryGetFloatValue(item + target + "X", ref BarPos[player, numplayer].X);
_ThemeLoaded &= xmlReader.TryGetFloatValue(item + target + "Y", ref BarPos[player, numplayer].Y);
_ThemeLoaded &= xmlReader.TryGetFloatValue(item + target + "Z", ref BarPos[player, numplayer].Z);
_ThemeLoaded &= xmlReader.TryGetFloatValue(item + target + "W", ref BarPos[player, numplayer].W);
_ThemeLoaded &= xmlReader.TryGetFloatValue(item + target + "H", ref BarPos[player, numplayer].H);
_Theme.BarPos[i].Name = "P" + (player + 1) + "N" + (numplayer + 1);
_Theme.BarPos[i].Rect = new SRectF(BarPos[player, numplayer]);
i++;
}
BarPos[player, numplayer] = new SRectF();
string target = "/BarPositions/P" + (player + 1) + "N" + (numplayer + 1);
_ThemeLoaded &= xmlReader.TryGetFloatValue(item + target + "X", ref BarPos[player, numplayer].X);
_ThemeLoaded &= xmlReader.TryGetFloatValue(item + target + "Y", ref BarPos[player, numplayer].Y);
_ThemeLoaded &= xmlReader.TryGetFloatValue(item + target + "Z", ref BarPos[player, numplayer].Z);
_ThemeLoaded &= xmlReader.TryGetFloatValue(item + target + "W", ref BarPos[player, numplayer].W);
_ThemeLoaded &= xmlReader.TryGetFloatValue(item + target + "H", ref BarPos[player, numplayer].H);
_Theme.BarPos[i].Name = "P" + (player + 1) + "N" + (numplayer + 1);
_Theme.BarPos[i].Rect = new SRectF(BarPos[player, numplayer]);
i++;
}
}
@@ -179,7 +164,6 @@ namespace VocaluxeLib.Menu.SingNotes
return _ThemeLoaded;
}
public void Reset()
{
_PlayerNotes.Clear();
@@ -317,7 +301,7 @@ namespace VocaluxeLib.Menu.SingNotes
);
_DrawNoteBG(rect, color, 1f, _PlayerNotes[n].Timer);
_DrawNote(rect, new SColorF(5f, 5f, 5f, 0.7f * _PlayerNotes[n].Alpha), 0.7f);
_DrawNote(rect, new SColorF(1f, 1f, 1f, 0.7f * _PlayerNotes[n].Alpha), 0.7f);
if (note.Type == ENoteType.Golden)
{
@@ -428,7 +412,7 @@ namespace VocaluxeLib.Menu.SingNotes
public void UnloadTextures() {}
public void LoadTextures()
public void LoadTextures()
{
foreach (SBarPosition bp in _Theme.BarPos)
{
@@ -471,9 +455,9 @@ namespace VocaluxeLib.Menu.SingNotes
var noteRect = new SRectF(rect.X + dw, rect.Y + dh, rect.W - 2 * dw, rect.H - 2 * dh, rect.Z);
CTexture noteBegin = CBase.Theme.GetSkinTexture(_Theme.SkinLeftName, _PartyModeID);
CTexture noteMiddle = CBase.Theme.GetSkinTexture(_Theme.SkinMiddleName, _PartyModeID);
CTexture noteEnd = CBase.Theme.GetSkinTexture(_Theme.SkinRightName, _PartyModeID);
CTextureRef noteBegin = CBase.Theme.GetSkinTexture(_Theme.SkinLeftName, _PartyModeID);
CTextureRef noteMiddle = CBase.Theme.GetSkinTexture(_Theme.SkinMiddleName, _PartyModeID);
CTextureRef noteEnd = CBase.Theme.GetSkinTexture(_Theme.SkinRightName, _PartyModeID);
//Width of each of the ends (round parts)
//Need 2 of them so use minimum
@@ -518,9 +502,9 @@ namespace VocaluxeLib.Menu.SingNotes
rect.Z
);
CTexture noteBackgroundBegin = CBase.Theme.GetSkinTexture(_Theme.SkinBackgroundLeftName, _PartyModeID);
CTexture noteBackgroundMiddle = CBase.Theme.GetSkinTexture(_Theme.SkinBackgroundMiddleName, _PartyModeID);
CTexture noteBackgroundEnd = CBase.Theme.GetSkinTexture(_Theme.SkinBackgroundRightName, _PartyModeID);
CTextureRef noteBackgroundBegin = CBase.Theme.GetSkinTexture(_Theme.SkinBackgroundLeftName, _PartyModeID);
CTextureRef noteBackgroundMiddle = CBase.Theme.GetSkinTexture(_Theme.SkinBackgroundMiddleName, _PartyModeID);
CTextureRef noteBackgroundEnd = CBase.Theme.GetSkinTexture(_Theme.SkinBackgroundRightName, _PartyModeID);
float dx = r.H * noteBackgroundBegin.OrigAspect;
if (2 * dx > r.W)
@@ -538,12 +522,13 @@ namespace VocaluxeLib.Menu.SingNotes
CBase.Drawing.DrawTexture(noteBackgroundEnd, new SRectF(r.X + r.W - dx, r.Y, dx, r.H, r.Z), col);
}
protected void _DrawNoteLines(SRectF rect, SColorF color)
private static void _DrawNoteLines(SRectF rect, SColorF color)
{
for (int i = 0; i < CBase.Settings.GetNumNoteLines() - 1; i++)
SRectF lineRect = new SRectF(rect) {H = 1.5f};
for (int i = 0; i < CBase.Settings.GetNumNoteLines(); i++)
{
float y = rect.Y + rect.H / CBase.Settings.GetNumNoteLines() * (i + 1);
CBase.Drawing.DrawColor(color, new SRectF(rect.X, y, rect.W, 1, -1.0f));
lineRect.Y = rect.Y + rect.H / CBase.Settings.GetNumNoteLines() * (i + 1);
CBase.Drawing.DrawRect(color, lineRect);
}
}
@@ -613,7 +598,7 @@ namespace VocaluxeLib.Menu.SingNotes
rect.Z
);
CTexture noteBegin = CBase.Theme.GetSkinTexture(_Theme.SkinLeftName, _PartyModeID);
CTextureRef noteBegin = CBase.Theme.GetSkinTexture(_Theme.SkinLeftName, _PartyModeID);
float dx = r.H * noteBegin.OrigAspect;
if (2 * dx > r.W)
dx = r.W / 2;
@@ -670,7 +655,7 @@ namespace VocaluxeLib.Menu.SingNotes
_PlayerNotes[n].Color.B,
_PlayerNotes[n].Color.A * _PlayerNotes[n].Alpha);
CTexture toneHelper = CBase.Theme.GetSkinTexture(_Theme.SkinToneHelperName, _PartyModeID);
CTextureRef toneHelper = CBase.Theme.GetSkinTexture(_Theme.SkinToneHelperName, _PartyModeID);
CBase.Drawing.DrawTexture(toneHelper, drawRect, color);
+1
View File
@@ -17,6 +17,7 @@
using System.Xml;
using VocaluxeLib.PartyModes;
using VocaluxeLib.Xml;
namespace VocaluxeLib.Menu.SongMenu
{
+11 -38
View File
@@ -23,34 +23,26 @@ using System.Xml.Serialization;
using VocaluxeLib.Draw;
using VocaluxeLib.PartyModes;
using VocaluxeLib.Songs;
using VocaluxeLib.Xml;
namespace VocaluxeLib.Menu.SongMenu
{
[XmlType("SongMenu")]
public struct SThemeSongMenu
{
[XmlAttributeAttribute(AttributeName = "Name")]
public string Name;
[XmlAttribute(AttributeName = "Name")] public string Name;
[XmlElement("CoverBackground")]
public string CoverBackgroundName;
[XmlElement("CoverBigBackground")]
public string CoverBigBackgroundName;
[XmlElement("DuetIcon")]
public string DuetIconName;
[XmlElement("VideoIcon")]
public string VideoIconName;
[XmlElement("MedleyCalcIcon")]
public string MedleyCalcIcon;
[XmlElement("MedleyTagIcon")]
public string MedleyTagIcon;
[XmlElement("Color")]
public SThemeColor Color;
[XmlElement("CoverBackground")] public string CoverBackgroundName;
[XmlElement("CoverBigBackground")] public string CoverBigBackgroundName;
[XmlElement("DuetIcon")] public string DuetIconName;
[XmlElement("VideoIcon")] public string VideoIconName;
[XmlElement("MedleyCalcIcon")] public string MedleyCalcIcon;
[XmlElement("MedleyTagIcon")] public string MedleyTagIcon;
[XmlElement("Color")] public SThemeColor Color;
//public SThemeSongMenuBook songMenuBook;
//public SThemeSongMenuDreidel songMenuDreidel;
//public SThemeSongMenuList songMenuList;
[XmlElement("SongMenuTileBoard")]
public SThemeSongMenuTileBoard SongMenuTileBoard;
public SThemeSongMenu(SThemeSongMenu theme)
@@ -69,65 +61,48 @@ namespace VocaluxeLib.Menu.SongMenu
public struct SThemeSongMenuTileBoard
{
[XmlElement("NumW")]
/// <summary>
/// Number of tiles horizontal
/// </summary>
public int NumW;
[XmlElement("NumH")]
/// <summary>
/// Number of tiles vertical
/// </summary>
public int NumH;
[XmlElement("NumWsmall")]
/// <summary>
/// Number of tiles horizontal in small-modus
/// </summary>
public int NumWsmall;
[XmlElement("NumHsmall")]
/// <summary>
/// Number of tiles vertical in small-modus
/// </summary>
public int NumHsmall;
[XmlElement("SpaceW")]
/// <summary>
/// Space between tiles horizontal
/// </summary>
public float SpaceW;
[XmlElement("SpaceH")]
/// <summary>
/// Space between tiles vertical
/// </summary>
public float SpaceH;
[XmlElement("TileRect")]
public SRectF TileRect;
[XmlElement("TileRectSmall")]
public SRectF TileRectSmall;
[XmlElement("TextArtist")]
public SThemeText TextArtist;
[XmlElement("TextTitle")]
public SThemeText TextTitle;
[XmlElement("TextSongLength")]
public SThemeText TextSongLength;
[XmlElement("StaticCoverBig")]
public SThemeStatic StaticCoverBig;
[XmlElement("StaticTextBG")]
public SThemeStatic StaticTextBG;
[XmlElement("StaticDuetIcon")]
public SThemeStatic StaticDuetIcon;
[XmlElement("StaticVideoIcon")]
public SThemeStatic StaticVideoIcon;
[XmlElement("StaticMedleyCalcIcon")]
public SThemeStatic StaticMedleyCalcIcon;
[XmlElement("StaticMedleyTagIcon")]
public SThemeStatic StaticMedleyTagIcon;
}
@@ -278,7 +253,6 @@ namespace VocaluxeLib.Menu.SongMenu
return _ThemeLoaded;
}
#endregion Theme
public virtual void Init()
@@ -294,7 +268,7 @@ namespace VocaluxeLib.Menu.SongMenu
}
public virtual void OnShow() {}
public virtual void OnHide()
{
if(CBase.Graphics.GetNextScreen() != EScreens.ScreenNames || CBase.Config.GetBackgroundMusicStatus() == EBackgroundMusicOffOn.TR_CONFIG_OFF)
@@ -373,7 +347,6 @@ namespace VocaluxeLib.Menu.SongMenu
_ColorInternal = CBase.Theme.GetColor(_Theme.Color.Name, _PartyModeID);
else
_ColorInternal = _Theme.Color.Color;
}
public void ReloadTextures()
@@ -17,13 +17,13 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using System.Xml;
using VocaluxeLib.Draw;
using VocaluxeLib.PartyModes;
using VocaluxeLib.Songs;
using VocaluxeLib.Xml;
namespace VocaluxeLib.Menu.SongMenu
{
@@ -38,8 +38,8 @@ namespace VocaluxeLib.Menu.SongMenu
private CStatic _MedleyCalcIcon;
private CStatic _MedleyTagIcon;
private CTexture _CoverBigBGTexture;
private CTexture _CoverBGTexture;
private CTextureRef _CoverBigBGTexture;
private CTextureRef _CoverBGTexture;
private CText _Artist;
private CText _Title;
@@ -494,20 +494,16 @@ namespace VocaluxeLib.Menu.SongMenu
_TextBG.Draw();
CTexture vidtex = CBase.BackgroundMusic.IsPlayingPreview() ? CBase.BackgroundMusic.GetVideoTexture() : null;
CTextureRef vidtex = CBase.BackgroundMusic.IsPlayingPreview() ? CBase.BackgroundMusic.GetVideoTexture() : null;
if (vidtex != null)
{
if (vidtex.Color.A < 1)
_CoverBig.Draw(EAspect.Crop);
var bounds = new RectangleF(_CoverBig.Rect.X, _CoverBig.Rect.Y, _CoverBig.Rect.W, _CoverBig.Rect.H);
RectangleF rect;
CHelper.SetRect(bounds, out rect, vidtex.OrigAspect, EAspect.Crop);
var vidRect = new SRectF(rect.X, rect.Y, rect.Width, rect.Height, _CoverBig.Rect.Z);
var vidRectBounds = new SRectF(bounds.X, bounds.Y, bounds.Width, bounds.Height, 0f);
SRectF rect = CHelper.FitInBounds(_CoverBig.Rect, vidtex.OrigAspect, EAspect.Crop);
CBase.Drawing.DrawTexture(vidtex, vidRect, vidtex.Color, vidRectBounds);
CBase.Drawing.DrawTextureReflection(vidtex, vidRect, vidtex.Color, vidRectBounds, _CoverBig.ReflectionSpace, _CoverBig.ReflectionHeight);
CBase.Drawing.DrawTexture(vidtex, rect);
CBase.Drawing.DrawTextureReflection(vidtex, rect, vidtex.Color, _CoverBig.ReflectionSpace, _CoverBig.ReflectionHeight);
}
else
_CoverBig.Draw(EAspect.Crop);
+1 -3
View File
@@ -32,11 +32,9 @@ namespace VocaluxeLib.PartyModes
public override void LoadTheme(string xmlPath)
{
_Warning = GetNewText();
_Warning.Height = 100f;
_Warning.Font.Height = 100f;
_Warning.X = 150;
_Warning.Y = 300;
_Warning.Font = "Normal";
_Warning.Style = EStyle.Normal;
_Warning.Color = new SColorF(1f, 0f, 0f, 1f);
_Warning.SelColor = new SColorF(1f, 0f, 0f, 1f);
_Warning.Text = "SOMETHING WENT WRONG!";
+4 -4
View File
@@ -25,10 +25,10 @@ namespace VocaluxeLib.Profile
{
public int ID;
private readonly string _FileName = "";
private CTexture _Texture;
private CTextureRef _Texture;
private const int _MaxNameLen = 12;
public CTexture Texture
public CTextureRef Texture
{
get { return _Texture; }
}
@@ -39,11 +39,11 @@ namespace VocaluxeLib.Profile
public static CAvatar GetAvatar(string fileName)
{
CTexture texture = CBase.Drawing.AddTexture(fileName);
CTextureRef texture = CBase.Drawing.AddTexture(fileName);
return texture == null ? null : new CAvatar(texture, fileName);
}
private CAvatar(CTexture texture, string fileName, int id = -1)
private CAvatar(CTextureRef texture, string fileName, int id = -1)
{
_Texture = texture;
_FileName = fileName;
+1
View File
@@ -18,6 +18,7 @@
using System;
using System.IO;
using System.Xml;
using VocaluxeLib.Xml;
namespace VocaluxeLib.Profile
{
+4 -4
View File
@@ -24,8 +24,8 @@ namespace VocaluxeLib.Songs
public class CCategory
{
public readonly string Name;
private CTexture _CoverTextureSmall;
private CTexture _CoverTextureBig;
private CTextureRef _CoverTextureSmall;
private CTextureRef _CoverTextureBig;
public readonly List<CSongPointer> Songs = new List<CSongPointer>();
public CCategory(string name)
@@ -33,14 +33,14 @@ namespace VocaluxeLib.Songs
Name = name;
}
public CTexture CoverTextureSmall
public CTextureRef CoverTextureSmall
{
get { return _CoverTextureSmall; }
set { _CoverTextureSmall = value; }
}
public CTexture CoverTextureBig
public CTextureRef CoverTextureBig
{
get { return _CoverTextureBig ?? _CoverTextureSmall; }
set
+4 -4
View File
@@ -78,8 +78,8 @@ namespace VocaluxeLib.Songs
public partial class CSong
{
private CTexture _CoverTextureSmall;
private CTexture _CoverTextureBig;
private CTextureRef _CoverTextureSmall;
private CTextureRef _CoverTextureBig;
public SMedley Medley;
@@ -104,7 +104,7 @@ namespace VocaluxeLib.Songs
public bool NotesLoaded { get; private set; }
public CTexture CoverTextureSmall
public CTextureRef CoverTextureSmall
{
get
{
@@ -116,7 +116,7 @@ namespace VocaluxeLib.Songs
set { _CoverTextureSmall = value; }
}
public CTexture CoverTextureBig
public CTextureRef CoverTextureBig
{
get { return _CoverTextureBig ?? _CoverTextureSmall; }
set { _CoverTextureBig = value; }
+100 -16
View File
@@ -17,6 +17,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Drawing;
using System.Windows.Forms;
@@ -25,21 +26,57 @@ using VocaluxeLib.Songs;
namespace VocaluxeLib
{
public enum ECoverGeneratorType
{
Default,
Folder,
Artist,
Letter,
Edition,
Genre,
Language,
Year,
Decade,
Date
}
public struct SMargin
{
public int Default;
public int Left, Right, Top, Bottom;
}
public struct SThemeCoverGeneratorText
{
public string Text;
public SThemeFont Font;
public SThemeColor Color;
public SMargin Margin;
public int Indent;
}
public struct SThemeCoverGenerator
{
public ECoverGeneratorType Type;
public SThemeCoverGeneratorText Text;
public SThemeColor BackgroundColor;
public string Image;
public float ImageAlpha;
public bool ShowFirstCover;
}
#region Drawing
public struct SColorF
{
[XmlElement("R")]
public float R;
[XmlElement("G")]
public float G;
[XmlElement("B")]
public float B;
[XmlElement("A")]
public float A;
[XmlElement("R")] public float R;
[XmlElement("G")] public float G;
[XmlElement("B")] public float B;
[XmlElement("A")] public float A;
public SColorF(float r, float g, float b, float a)
{
Debug.Assert(r.IsInRange(0, 1) && g.IsInRange(0, 1) && b.IsInRange(0, 1));
Debug.Assert(a.IsInRange(0, 1));
R = r;
G = g;
B = b;
@@ -69,14 +106,30 @@ namespace VocaluxeLib
public string Name;
//Needed for serialization
public bool ColorSpecified { get { return String.IsNullOrEmpty(Name); } }
public bool NameSpecified { get { return !String.IsNullOrEmpty(Name); } }
public bool ColorSpecified
{
get { return String.IsNullOrEmpty(Name); }
}
public bool NameSpecified
{
get { return !String.IsNullOrEmpty(Name); }
}
public SThemeColor(SThemeColor theme)
{
Color = new SColorF(theme.Color);
Name = theme.Name;
}
public bool Get(int partyModeId, out SColorF color)
{
if (String.IsNullOrEmpty(Name))
{
color = Color;
return true;
}
return CBase.Theme.GetColor(Name, CBase.Theme.GetSkinIndex(partyModeId), out color);
}
}
public struct SRectF
@@ -86,8 +139,24 @@ namespace VocaluxeLib
public float W;
public float H;
public float Z;
[XmlIgnore]
public float Rotation; //0..360°
[XmlIgnore] public float Rotation; //0..360°
public float Right
{
get { return X + W; }
}
public float Bottom
{
get { return Y + H; }
}
public Size SizeI
{
get { return new Size((int)W, (int)H); }
}
public SizeF Size
{
get { return new SizeF(W, H); }
}
public SRectF(float x, float y, float w, float h, float z)
{
@@ -108,19 +177,34 @@ namespace VocaluxeLib
Z = rect.Z;
Rotation = 0f;
}
public SRectF(Rectangle rect)
{
X = rect.X;
Y = rect.Y;
W = rect.Width;
H = rect.Height;
Z = 0;
Rotation = 0;
}
}
[XmlRoot("Reflection")]
public struct SReflection
{
[XmlAttributeAttribute(AttributeName = "Enabled")]
public bool Enabled;
[XmlAttribute(AttributeName = "Enabled")] public bool Enabled;
public float Height;
public float Space;
//Needed for serialization
public bool HeightSpecified { get { return Enabled; } }
public bool SpaceSpecified { get { return Enabled; } }
public bool HeightSpecified
{
get { return Enabled; }
}
public bool SpaceSpecified
{
get { return Enabled; }
}
public SReflection(bool enabled, float height, float space)
{
+10 -15
View File
@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using VocaluxeLib.Draw;
using VocaluxeLib.Songs;
@@ -14,7 +13,7 @@ namespace VocaluxeLib.Utils.Player
private CSong _Song;
private bool _VideoEnabled;
private int _Video = -1;
private CTexture _CurrentVideoTexture;
private CTextureRef _CurrentVideoTexture;
private CFading _VideoFading;
public bool VideoEnabled
@@ -41,7 +40,7 @@ namespace VocaluxeLib.Utils.Player
}
public bool SongHasVideo
{
get { return _Song != null && File.Exists(Path.Combine(_Song.Folder,_Song.VideoFileName)); }
get { return _Song != null && File.Exists(Path.Combine(_Song.Folder, _Song.VideoFileName)); }
}
public string ArtistAndTitle
@@ -56,7 +55,7 @@ namespace VocaluxeLib.Utils.Player
}
}
public CTexture Cover
public CTextureRef Cover
{
get { return _Song == null ? CBase.Cover.GetNoCover() : _Song.CoverTextureBig; }
}
@@ -66,11 +65,10 @@ namespace VocaluxeLib.Utils.Player
get { return _StreamID != -1; }
}
public CSongPlayer(bool loop = false) : base(loop) { }
public CSongPlayer(bool loop = false) : base(loop) {}
public CSongPlayer(CSong song, bool loop = false, float position = 0f, bool autoplay = false)
: base(Path.Combine(song.Folder,song.MP3FileName), loop, position, autoplay)
: base(Path.Combine(song.Folder, song.MP3FileName), loop, position, autoplay)
{
_Song = song;
_LoadVideo();
@@ -82,7 +80,7 @@ namespace VocaluxeLib.Utils.Player
_Song = null;
}
public CTexture GetVideoTexture()
public CTextureRef GetVideoTexture()
{
if (_Video == -1 || _Song == null)
return null;
@@ -101,7 +99,7 @@ namespace VocaluxeLib.Utils.Player
return null;
}
public void Load(CSong song, float position = 0f, bool autoplay = false)
public void Load(CSong song, float position = 0f, bool autoplay = false)
{
if (song == null)
return;
@@ -109,7 +107,7 @@ namespace VocaluxeLib.Utils.Player
Stop();
_Song = song;
base.Load(Path.Combine(song.Folder, song.MP3FileName), position, false);
_LoadVideo();
@@ -155,13 +153,10 @@ namespace VocaluxeLib.Utils.Player
CBase.Video.Pause(_Video);
CBase.Video.Skip(_Video, CBase.Sound.GetPosition(_StreamID) + _FadeTime, _Song.VideoGap);
}
else if(_Video != -1)
{
else if (_Video != -1)
CBase.Video.Resume(_Video);
}
base.TogglePause();
}
private void _LoadVideo()
{
@@ -182,4 +177,4 @@ namespace VocaluxeLib.Utils.Player
}
}
}
}
}
+6 -2
View File
@@ -76,7 +76,9 @@
<Reference Include="System.XML" />
</ItemGroup>
<ItemGroup>
<Compile Include="CEncoding.cs" />
<Compile Include="CFading.cs" />
<Compile Include="CFont.cs" />
<Compile Include="Extensions.cs" />
<Compile Include="GlobalSuppressions.cs" />
<Compile Include="IBasic.cs" />
@@ -100,8 +102,9 @@
<Compile Include="Menu\CStatic.cs" />
<Compile Include="Menu\CText.cs" />
<Compile Include="Menu\CScreenSetting.cs" />
<Compile Include="Draw\CTexture.cs" />
<Compile Include="CXMLReader.cs" />
<Compile Include="Draw\CTextureRef.cs" />
<Compile Include="Xml\CXmlDeserializer.cs" />
<Compile Include="Xml\CXMLReader.cs" />
<Compile Include="Enums.cs" />
<Compile Include="Menu\IMenu.cs" />
<Compile Include="Menu\IMenuElement.cs" />
@@ -137,6 +140,7 @@
<Compile Include="Utils\CWavFile.cs" />
<Compile Include="Utils\Player\CSongPlayer.cs" />
<Compile Include="Utils\Player\CSoundPlayer.cs" />
<Compile Include="Xml\CXmlReaderBase.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
@@ -19,9 +19,9 @@ using System;
using System.Collections.Generic;
using System.Xml.XPath;
namespace VocaluxeLib
namespace VocaluxeLib.Xml
{
public class CXMLReader
public class CXMLReader : CXmlDeserializer
{
private readonly XPathNavigator _Navigator;
private readonly String _FilePath;
@@ -57,55 +57,17 @@ namespace VocaluxeLib
}
}
public bool TryGetEnumValue<T>(string xPath, ref T value)
where T : struct
{
string val;
if (GetValue(xPath, out val, Enum.GetName(typeof(T), value)))
return CHelper.TryParse(val, out value, true);
return false;
}
public bool TryGetIntValue(string xPath, ref int value)
{
string val;
if (GetValue(xPath, out val, value.ToString()))
return int.TryParse(val, out value);
return false;
}
public bool TryGetIntValueRange(string xPath, ref int value, int min = 0, int max = 100)
{
bool result = TryGetIntValue(xPath, ref value);
if (result)
value = value.Clamp(min, max);
return result;
}
public bool TryGetFloatValue(string xPath, ref float value)
{
string val;
return GetValue(xPath, out val, value.ToString()) && CHelper.TryParse(val, out value);
}
public bool TryGetColorFromRGBA(string xPath, ref SColorF value)
{
bool result = true;
result &= TryGetFloatValue(xPath + "/R", ref value.R);
result &= TryGetFloatValue(xPath + "/G", ref value.G);
result &= TryGetFloatValue(xPath + "/B", ref value.B);
result &= TryGetFloatValue(xPath + "/A", ref value.A);
if (result)
{
value.R = value.R.Clamp(0f, 1f);
value.G = value.G.Clamp(0f, 1f);
value.B = value.B.Clamp(0f, 1f);
value.A = value.A.Clamp(0f, 1f);
}
result &= TryGetNormalizedFloatValue(xPath + "/R", ref value.R);
result &= TryGetNormalizedFloatValue(xPath + "/G", ref value.G);
result &= TryGetNormalizedFloatValue(xPath + "/B", ref value.B);
result &= TryGetNormalizedFloatValue(xPath + "/A", ref value.A);
return result;
}
public bool GetValue(string xPath, out string value, string defaultValue = "")
public override bool GetValue(string xPath, out string value, string defaultValue = "")
{
int resultCt = 0;
string val = string.Empty;
@@ -128,6 +90,19 @@ namespace VocaluxeLib
return true;
}
public override bool GetAttribute(string xPath, string attribute, out string value)
{
_Navigator.MoveToRoot();
XPathNodeIterator iterator = _Navigator.Select(xPath);
if (iterator.MoveNext())
{
value = iterator.Current.GetAttribute(attribute, "");
return true;
}
value = "";
return false;
}
public List<string> GetNames(string xPath)
{
var values = new List<string>();
+68
View File
@@ -0,0 +1,68 @@
using System.Linq;
namespace VocaluxeLib.Xml
{
public abstract class CXmlDeserializer : CXmlReaderBase
{
public bool Read(string xPath, out SThemeFont el)
{
el = new SThemeFont();
bool ok = true;
ok &= GetValue(xPath + "/Name", out el.Name);
ok &= TryGetFloatValue(xPath + "/Size", ref el.Size);
ok &= TryGetEnumValue(xPath + "/Style", ref el.Style);
return ok;
}
public bool Read(string xPath, out SMargin el)
{
el = new SMargin();
bool ok = true;
bool defOk = TryGetIntValue(xPath + "/Default", ref el.Default);
ok &= TryGetIntValue(xPath + "/Left", ref el.Left, el.Default);
ok &= TryGetIntValue(xPath + "/Right", ref el.Right, el.Default);
ok &= TryGetIntValue(xPath + "/Top", ref el.Top, el.Default);
ok &= TryGetIntValue(xPath + "/Bottom", ref el.Bottom, el.Default);
return ok || defOk;
}
public bool Read(string xPath, out SThemeCoverGeneratorText el)
{
el = new SThemeCoverGeneratorText();
bool ok = true;
ok &= GetValue(xPath + "/Text", out el.Text);
ok &= Read(xPath + "/Font", out el.Font);
ok &= Read(xPath + "/Color", out el.Color);
ok &= Read(xPath + "/Margin", out el.Margin);
if (ok)
TryGetIntValue(xPath + "/Indent", ref el.Indent, 6 * (el.Margin.Left + el.Margin.Right) / 2);
return ok;
}
public bool Read(string xPath, out SThemeColor el)
{
el = new SThemeColor();
bool ok = true;
ok &= TryGetNormalizedFloatValue(xPath + "/R", ref el.Color.R);
ok &= TryGetNormalizedFloatValue(xPath + "/G", ref el.Color.G);
ok &= TryGetNormalizedFloatValue(xPath + "/B", ref el.Color.B);
ok &= TryGetNormalizedFloatValue(xPath + "/A", ref el.Color.A);
if (!ok)
ok = GetValue(xPath, out el.Name) && !el.Name.Contains('<');
return ok;
}
public bool Read(string xPath, out SThemeCoverGenerator el)
{
el = new SThemeCoverGenerator();
bool ok = true;
ok &= TryGetEnumValue(xPath + "/Type", ref el.Type);
ok &= Read(xPath + "/Text", out el.Text);
ok &= Read(xPath + "/BackgroundColor", out el.BackgroundColor);
ok &= GetValue(xPath + "/Image", out el.Image);
TryGetNormalizedFloatValue(xPath + "/ImageAlpha", ref el.ImageAlpha, 0.5f);
TryGetBoolValue(xPath + "/ShowFirstCover", out el.ShowFirstCover);
return ok;
}
}
}
+61
View File
@@ -0,0 +1,61 @@
using System;
namespace VocaluxeLib.Xml
{
/// <summary>
/// Base class that provides basic methods for reading xml, while the actual XML implementation is still abstract to allow different implementations
/// </summary>
public abstract class CXmlReaderBase
{
public abstract bool GetValue(string xPath, out string value, string defaultValue = "");
public abstract bool GetAttribute(string xPath, string attribute, out string value);
public bool TryGetBoolValue(string xPath, out bool value, bool defaultValue = false)
{
value = defaultValue;
string val;
return GetValue(xPath, out val) && bool.TryParse(val, out value);
}
public bool TryGetIntValue(string xPath, ref int value, int? defaultValue = null)
{
string val;
bool ok = GetValue(xPath, out val) && int.TryParse(val, out value);
if (!ok && defaultValue.HasValue)
value = defaultValue.Value;
return ok;
}
public bool TryGetFloatValue(string xPath, ref float value)
{
string val;
return GetValue(xPath, out val, value.ToString()) && CHelper.TryParse(val, out value);
}
public bool TryGetEnumValue<T>(string xPath, ref T value) where T : struct
{
string val;
return GetValue(xPath, out val, Enum.GetName(typeof(T), value)) && CHelper.TryParse(val, out value, true);
}
public bool TryGetIntValueRange(string xPath, ref int value, int min = 0, int max = 100)
{
return TryGetIntValue(xPath, ref value) && value.IsInRange(min, max);
}
/// <summary>
/// Gets a normalized (0&lt;=x&lt;=1) float value
/// </summary>
/// <param name="xPath"></param>
/// <param name="value"></param>
/// <param name="defaultValue"></param>
/// <returns>True if exists and is normalized</returns>
public bool TryGetNormalizedFloatValue(string xPath, ref float value, float defaultValue = 0)
{
bool ok = TryGetFloatValue(xPath, ref value) && value.IsInRange(0f, 1f);
if (!ok)
value = defaultValue;
return ok;
}
}
}