diff --git a/.gitignore b/.gitignore
index f9e43ee9..e4196b50 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,6 +28,8 @@ tx.exe
*.vshost.*
*.userprefs
*.user
+*.VC.opendb
+*:VC.db
/*.vsp
/*.ctl
/Output/Config.xml
diff --git a/Output/Languages/English.xml b/Output/Languages/English.xml
index 2cd71c39..27174a7d 100644
--- a/Output/Languages/English.xml
+++ b/Output/Languages/English.xml
@@ -47,6 +47,7 @@
Level 3
Max
List
+ List and Record
Dreidel
Tiles
Book
diff --git a/Output/Languages/German.xml b/Output/Languages/German.xml
index a076eb67..0463d7ca 100644
--- a/Output/Languages/German.xml
+++ b/Output/Languages/German.xml
@@ -47,6 +47,7 @@
Level 3
Maximal
Song-Liste
+ Song-Liste & Record
Dreidel
TileBoard
Book
diff --git a/Output/PartyModes/ChallengeRounds.xml b/Output/PartyModes/ChallengeRounds.xml
new file mode 100644
index 00000000..d59600c7
--- /dev/null
+++ b/Output/PartyModes/ChallengeRounds.xml
@@ -0,0 +1,19 @@
+
+
+ 2
+
+ TR_PARTYMODE_NAME
+ Pr3di
+ TR_PARTYMODE_DESCRIPTION
+ ChallengeRounds
+ CPartyModeChallengeRounds
+ 0
+ 1
+ TR_PARTYMODE_AUDIENCE
+
+
+ CPartyScreenChallengeRoundsMain
+ CPartyScreenChallengeRoundsConfig
+ CPartyScreenChallengeRoundsNames
+
+
diff --git a/Output/PartyModes/ChallengeRounds/Languages/English.xml b/Output/PartyModes/ChallengeRounds/Languages/English.xml
new file mode 100644
index 00000000..03a2b1ed
--- /dev/null
+++ b/Output/PartyModes/ChallengeRounds/Languages/English.xml
@@ -0,0 +1,32 @@
+
+
+ English
+ Challenge Mode with Rounds
+ Play some challenge rounds.
+ For all who are interested in duel fights.
+ Next
+ Back
+ Start
+ Exit
+ Yes
+ No
+ Next Round
+ Challenge Mode with Rounds: Configuration
+ Number of players
+ Number of mics
+ Number of rounds
+ Number of jokers
+ Refill jokers every round
+ Challenge Mode with Rounds: Choose Player
+ Select random
+ Challenge Mode with Rounds: Overview
+ Pos
+ Name
+ Rounds
+ Wins
+ Sing Points
+ Score
+ Do you really want to exit?
+ Player of next round:
+ All rounds were sung! And the winner is...
+
diff --git a/Output/PartyModes/ChallengeRounds/Languages/German.xml b/Output/PartyModes/ChallengeRounds/Languages/German.xml
new file mode 100644
index 00000000..c8919091
--- /dev/null
+++ b/Output/PartyModes/ChallengeRounds/Languages/German.xml
@@ -0,0 +1,32 @@
+
+
+ Deutsch
+ Challenge Modus mit Runden
+ Spiele einen Wettkampfmodus
+ Für alle, die Spaß am Wettkampf haben.
+ Weiter
+ Zurück
+ Start
+ Exit
+ Ja
+ Nein
+ Nächste Runde
+ Challenge Modus mit Runden: Einstellungen
+ Anzahl der Spieler
+ Anzahl der Mikrofone
+ Anzahl der Runden
+ Joker-Anzahl
+ Joker nach jeder Runde auffüllen
+ Challenge Modus mit Runden: Spielerwahl
+ Zufällig auswählen
+ Challenge Modus mit Runden: Übersicht
+ Pos
+ Name
+ Runden
+ Siege
+ Sing-Punkte
+ Punkte
+ Challenge-Mode wirklich beenden?
+ Spieler der nächsten Runde:
+ Alle Runden wurden gesungen! Und der Gewinner ist...
+
diff --git a/Output/PartyModes/ChallengeRounds/Themes/Default.xml b/Output/PartyModes/ChallengeRounds/Themes/Default.xml
new file mode 100644
index 00000000..9f682128
--- /dev/null
+++ b/Output/PartyModes/ChallengeRounds/Themes/Default.xml
@@ -0,0 +1,10 @@
+
+
+ 5
+
+ Default
+ Pr3di
+ 0
+ 1
+
+
\ No newline at end of file
diff --git a/Output/PartyModes/ChallengeRounds/Themes/Default/Default.xml b/Output/PartyModes/ChallengeRounds/Themes/Default/Default.xml
new file mode 100644
index 00000000..44dbf62f
--- /dev/null
+++ b/Output/PartyModes/ChallengeRounds/Themes/Default/Default.xml
@@ -0,0 +1,16 @@
+
+
+ 4
+
+ Default
+ Pr3di
+ 0
+ 1
+
+
+
+
+
+
+
+
diff --git a/Output/PartyModes/ChallengeRounds/Themes/Default/Screens/PartyScreenChallengeRoundsConfig.xml b/Output/PartyModes/ChallengeRounds/Themes/Default/Screens/PartyScreenChallengeRoundsConfig.xml
new file mode 100644
index 00000000..c5fdb84a
--- /dev/null
+++ b/Output/PartyModes/ChallengeRounds/Themes/Default/Screens/PartyScreenChallengeRoundsConfig.xml
@@ -0,0 +1,407 @@
+
+
+
+ PartyScreenChallengeRoundsConfig
+ 3
+
+
+
+ Video
+
+
+ BG_Default
+
+
+
+
+
+ Menu
+
+
+ 40
+ 40
+ 1200
+ 50
+ 0
+
+
+
+
+
+ 640
+ 48
+ 0
+ 27
+ 0
+
+
+ Center
+ Center
+
+ Outline
+ TR_SCREENCONFIG_TITLE
+
+
+ 75
+ 105
+ 0
+ 27
+ 0
+
+
+ Left
+ Center
+
+ Outline
+ TR_SCREENCONFIG_NUMPLAYERS
+
+
+ 75
+ 165
+ 0
+ 27
+ 0
+
+
+ Left
+ Center
+
+ Outline
+ TR_SCREENCONFIG_NUMMICS
+
+
+ 75
+ 225
+ 0
+ 27
+ 0
+
+
+ Left
+ Center
+
+ Outline
+ TR_SCREENCONFIG_NUMROUNDS
+
+
+ 75
+ 285
+ 0
+ 27
+ 0
+
+
+ Left
+ Center
+
+ Outline
+ TR_SCREENCONFIG_NUMJOKERS
+
+
+ 75
+ 345
+ 0
+ 27
+ 0
+
+
+ Left
+ Center
+
+ Outline
+ TR_SCREENCONFIG_REFILLJOKERS
+
+
+
+
+
+
+
+
+
+
+
+ SelectSlideArrowLeft
+ SelectSlideArrowRight
+ SelectSlide
+ SelectSlideArrowLeft
+ SelectSlideArrowRight
+
+ 500
+ 100
+ 700
+ 50
+ 0
+
+
+ 505
+ 105
+ 40
+ 40
+ 0
+
+
+ 1170
+ 105
+ 40
+ 40
+ 0
+
+
+
+
+
+
+
+ 27
+ 50
+ 0
+ 205.33
+ Outline
+ Bold
+ 9
+
+
+
+ SelectSlideArrowLeft
+ SelectSlideArrowRight
+ SelectSlide
+ SelectSlideArrowLeft
+ SelectSlideArrowRight
+
+ 500
+ 160
+ 700
+ 50
+ 0
+
+
+ 505
+ 165
+ 40
+ 40
+ 0
+
+
+ 1170
+ 165
+ 40
+ 40
+ 0
+
+
+
+
+
+
+
+ 27
+ 50
+ 0
+ 205.33
+ Outline
+ Bold
+ 2
+
+
+
+ SelectSlideArrowLeft
+ SelectSlideArrowRight
+ SelectSlide
+ SelectSlideArrowLeft
+ SelectSlideArrowRight
+
+ 500
+ 220
+ 700
+ 50
+ 0
+
+
+ 505
+ 225
+ 40
+ 40
+ 0
+
+
+ 1170
+ 225
+ 40
+ 40
+ 0
+
+
+
+
+
+
+
+ 27
+ 50
+ 0
+ 205.33
+ Outline
+ Bold
+ 10
+
+
+
+ SelectSlideArrowLeft
+ SelectSlideArrowRight
+ SelectSlide
+ SelectSlideArrowLeft
+ SelectSlideArrowRight
+
+ 500
+ 280
+ 700
+ 50
+ 0
+
+
+ 505
+ 285
+ 40
+ 40
+ 0
+
+
+ 1170
+ 285
+ 40
+ 40
+ 0
+
+
+
+
+
+
+
+ 27
+ 50
+ 0
+ 205.33
+ Outline
+ Bold
+ 10
+
+
+
+ SelectSlideArrowLeft
+ SelectSlideArrowRight
+ SelectSlide
+ SelectSlideArrowLeft
+ SelectSlideArrowRight
+
+ 500
+ 340
+ 700
+ 50
+ 0
+
+
+ 505
+ 345
+ 40
+ 40
+ 0
+
+
+ 1170
+ 345
+ 40
+ 40
+ 0
+
+
+
+
+
+
+
+ 27
+ 50
+ 0
+ 205.33
+ Outline
+ Bold
+ 2
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Output/PartyModes/ChallengeRounds/Themes/Default/Screens/PartyScreenChallengeRoundsMain.xml b/Output/PartyModes/ChallengeRounds/Themes/Default/Screens/PartyScreenChallengeRoundsMain.xml
new file mode 100644
index 00000000..54e1dc93
--- /dev/null
+++ b/Output/PartyModes/ChallengeRounds/Themes/Default/Screens/PartyScreenChallengeRoundsMain.xml
@@ -0,0 +1,557 @@
+
+
+
+ PartyScreenChallengeRoundsMain
+ 1
+
+
+
+ Video
+
+
+ BG_Default
+
+
+
+
+
+ Menu
+
+
+ 40
+ 40
+ 1200
+ 50
+ 0
+
+
+
+ PopupBG
+
+
+ 0
+ 0
+ 1280
+ 720
+ -1
+
+
+
+
+
+
+ 0
+ 0
+ 100
+ 100
+ 0
+
+
+
+
+
+ 640
+ 48
+ 0
+ 27
+ 0
+
+
+ Center
+ Center
+
+ Outline
+ TR_SCREENMAIN_TITLE
+
+
+ 40
+ 102
+ 0
+ 27
+ 0
+
+
+ Right
+ Center
+
+ Outline
+ TR_SCREENMAIN_TABLE_POS
+
+
+ 50
+ 102
+ 0
+ 27
+ 130
+
+
+ Left
+ Center
+
+ Outline
+ TR_SCREENMAIN_TABLE_PLAYERNAME
+
+
+ 260
+ 102
+ 0
+ 27
+ 0
+
+
+ Right
+ Center
+
+ Outline
+ TR_SCREENMAIN_TABLE_NUMPLAYED
+
+
+ 340
+ 102
+ 0
+ 27
+ 0
+
+
+ Right
+ Center
+
+ Outline
+ TR_SCREENMAIN_TABLE_WON
+
+
+ 490
+ 102
+ 0
+ 27
+ 0
+
+
+ Right
+ Center
+
+ Outline
+ TR_SCREENMAIN_TABLE_SINGPOINTS
+
+
+ 590
+ 102
+ 0
+ 27
+ 0
+
+
+ Right
+ Center
+
+ Outline
+ TR_SCREENMAIN_TABLE_GAMEPOINTS
+
+
+ 0
+ 0
+ 0
+ 27
+ 100
+
+
+ Center
+ Center
+
+ Outline
+
+
+
+ 640
+ 265
+ -1.01
+ 27
+ 380
+
+
+ Center
+ Center
+
+ Outline
+ TR_SCREENMAIN_POPUP_REALLYEXIT
+
+
+ 660
+ 102
+ 0
+ 27
+ 0
+
+
+ Right
+ Center
+
+ Outline
+ 1)
+
+
+ 0
+ 0
+ 0
+ 27
+ 0
+
+
+ Center
+ Center
+
+ Outline
+
+
+
+ 0
+ 0
+ 0
+ 27
+ 0
+
+
+ Center
+ Center
+
+ Outline
+
+
+
+ 640
+ 520
+ 0
+ 44
+ 0
+
+
+ Center
+ Center
+
+ Outline
+ TR_SCREENMAIN_FINISH
+
+
+ 640
+ 575
+ 0
+ 31
+ 770
+
+
+ Center
+ Center
+
+ Outline
+
+
+
+ 640
+ 515
+ 0
+ 27
+ 0
+
+
+ Center
+ Center
+
+ Outline
+ TR_SCREENMAIN_NEXT_PLAYER
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Output/PartyModes/ChallengeRounds/Themes/Default/Screens/PartyScreenChallengeRoundsNames.xml b/Output/PartyModes/ChallengeRounds/Themes/Default/Screens/PartyScreenChallengeRoundsNames.xml
new file mode 100644
index 00000000..ae27e646
--- /dev/null
+++ b/Output/PartyModes/ChallengeRounds/Themes/Default/Screens/PartyScreenChallengeRoundsNames.xml
@@ -0,0 +1,387 @@
+
+
+
+ PartyScreenChallengeRoundsNames
+ 1
+
+
+
+ Video
+
+
+ BG_Default
+
+
+
+
+
+ Menu
+
+
+ 40
+ 40
+ 1200
+ 50
+ 0
+
+
+
+
+
+ 640
+ 48
+ 0
+ 27
+ 0
+
+
+ Center
+ Center
+
+ Outline
+ TR_SCREENNAMES_TITLE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ SelectSlideArrowLeft
+ SelectSlideArrowRight
+ SelectSlide
+ SelectSlideArrowLeft
+ SelectSlideArrowRight
+
+ 40
+ 100
+ 1200
+ 50
+ 0
+
+
+ 45
+ 105
+ 40
+ 40
+ 0
+
+
+ 1170
+ 105
+ 40
+ 40
+ 0
+
+
+
+
+
+
+
+ 27
+ 50
+ 0
+ 205.33
+ Outline
+ Bold
+ 2
+
+
+
+ SelectSlideArrowLeft
+ SelectSlideArrowRight
+ SelectSlidePlayer
+ SelectSlideArrowLeft
+ SelectSlideArrowRight
+
+ 40
+ 160
+ 1200
+ 150
+ 0
+
+
+ 45
+ 210
+ 40
+ 40
+ 0
+
+
+ 1170
+ 210
+ 40
+ 40
+ 0
+
+
+
+
+
+
+
+ 27
+ 50
+ 5
+ 205.33
+ Outline
+ Bold
+ 8
+
+
+
+
+
+
+ 42
+ 327
+ 1200
+ 393
+ 0
+
+ CoverTile
+
+ 1
+ 1
+ 1
+ 0.2
+
+ PlayerSelector
+
+ 100
+ 100
+ 10
+ 2
+ 20.71
+ 30
+
+ 2
+ 17
+ Outline
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Output/Themes/Ambient/Screens/ScreenSong.xml b/Output/Themes/Ambient/Screens/ScreenSong.xml
index 890173ac..c075827f 100644
--- a/Output/Themes/Ambient/Screens/ScreenSong.xml
+++ b/Output/Themes/Ambient/Screens/ScreenSong.xml
@@ -58,10 +58,10 @@
- 1070
+ 1120
65
-2.11
- 42
+ 32
350
@@ -72,10 +72,10 @@
- 1070
+ 1120
135
-2.11
- 42
+ 32
350
@@ -86,10 +86,10 @@
- 1070
+ 1120
205
-2.11
- 42
+ 32
350
@@ -100,10 +100,10 @@
- 1070
+ 1120
275
-2.11
- 42
+ 32
350
@@ -114,10 +114,10 @@
- 1070
+ 1120
345
-2.11
- 42
+ 32
350
@@ -128,10 +128,10 @@
- 1070
+ 1120
415
-2.11
- 42
+ 32
350
@@ -225,20 +225,20 @@
Random
Random
- 980
+ 1050
50
- 80
- 80
+ 60
+ 60
-1.01
0.5
- 40
- 23
+ 30
+ 15
0
- 34
- 60
+ 30
+ 50
Center
@@ -252,19 +252,19 @@
Random
Random
- 980
+ 1050
120
- 80
- 80
+ 60
+ 60
-1.01
0.5
- 40
- 23
+ 30
+ 15
0
- 34
+ 30
60
@@ -279,19 +279,19 @@
Random
Random
- 980
+ 1050
190
- 80
- 80
+ 60
+ 60
-1.01
0.5
- 40
- 23
+ 30
+ 15
0
- 34
+ 30
60
@@ -306,19 +306,19 @@
Random
Random
- 980
+ 1050
260
- 80
- 80
+ 60
+ 60
-1.01
0.5
- 40
- 23
+ 30
+ 15
0
- 34
+ 30
60
@@ -333,19 +333,19 @@
Random
Random
- 980
+ 1050
330
- 80
- 80
+ 60
+ 60
-1.01
0.5
- 40
- 23
+ 30
+ 15
0
- 34
+ 30
60
@@ -360,19 +360,19 @@
Random
Random
- 980
+ 1050
400
- 80
- 80
+ 60
+ 60
-1.01
0.5
- 40
- 23
+ 30
+ 15
0
- 34
+ 30
60
@@ -630,7 +630,7 @@
Button
Button
- 985
+ 1050
500
150
50
@@ -987,6 +987,140 @@
+
+ 8
+ 10
+ 10
+
+ 640
+ 40
+ 550
+ 550
+ -1
+
+
+ 640
+ 40
+ 395
+ 550
+ -1
+
+
+ 400
+ 420
+ 280
+ 210
+ -1
+
+
+ 222
+ 416
+ -1.01
+ 39
+ 340
+
+
+ Center
+ Top
+
+ Outline
+
+
+
+ 222
+ 456
+ -1.01
+ 32
+ 340
+
+
+ Center
+ Top
+
+ Outline
+
+
+
+ 222
+ 490
+ -1.01
+ 28
+ 340
+
+
+ Center
+ Top
+
+ Outline
+
+
+
+ CoverBackground
+
+
+ 40
+ 40
+ 640
+ 360
+ -1
+
+
+
+ CoverBackground
+
+
+ 40
+ 40
+ 640
+ 550
+ -1
+
+
+
+ DuetIcon
+
+
+ 200
+ 530
+ 40
+ 40
+ -1
+
+
+
+ VideoIcon
+
+
+ 120
+ 530
+ 40
+ 40
+ -1
+
+
+
+ MedleyCalcIcon
+
+
+ 280
+ 530
+ 40
+ 40
+ -1
+
+
+
+ MedleyTagIcon
+
+
+ 280
+ 530
+ 40
+ 40
+ -1
+
+
+
diff --git a/PartyModes/PartyModeChallenge/PartyModeChallenge.csproj b/PartyModes/PartyModeChallenge/PartyModeChallenge.csproj
index 1d0a49a9..852f916a 100644
--- a/PartyModes/PartyModeChallenge/PartyModeChallenge.csproj
+++ b/PartyModes/PartyModeChallenge/PartyModeChallenge.csproj
@@ -109,4 +109,4 @@ rm -f "$(SolutionDir)Output\PartyModes\$(TargetName)\Code\GlobalSuppressions.cs"
-->
-
+
\ No newline at end of file
diff --git a/PartyModes/PartyModeChallengeRounds/CChallengeRounds.cs b/PartyModes/PartyModeChallengeRounds/CChallengeRounds.cs
new file mode 100644
index 00000000..3710a3b9
--- /dev/null
+++ b/PartyModes/PartyModeChallengeRounds/CChallengeRounds.cs
@@ -0,0 +1,196 @@
+#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 .
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using VocaluxeLib.Utils.Combinatorics;
+
+namespace VocaluxeLib.PartyModes.ChallengeRounds
+{
+ public class CChallengeRounds
+ {
+ private readonly List _Rounds = new List();
+
+ public int Count
+ {
+ get { return _Rounds.Count; }
+ }
+
+ public CRound this[int index]
+ {
+ get { return _Rounds[index]; }
+ }
+
+ public CChallengeRounds(int numRounds, int numPlayer, int playersPerRound)
+ {
+ if (numRounds < 1 || numPlayer < 1 || playersPerRound < 1)
+ throw new ArgumentException("Invalid paramters for the rounds");
+
+ if (playersPerRound > numPlayer)
+ playersPerRound = numPlayer;
+
+ _BuildRounds(numRounds, numPlayer, playersPerRound);
+ if (Count > numRounds)
+ {
+ //Try again and take the better one
+ List old = new List(_Rounds);
+ _Rounds.Clear();
+ _BuildRounds(numRounds, numPlayer, playersPerRound);
+ if (Count > old.Count)
+ {
+ _Rounds.Clear();
+ _Rounds.AddRange(old);
+ }
+ }
+ }
+
+ ///
+ /// Divides players in 2 categories: Those how sung the most and the others
+ ///
+ /// List matching the playerIndex to the number of songs sung
+ private static List _GetPlayersForRound(IList numSung)
+ {
+ List mustSing = new List();
+ int max = numSung.Max();
+ for (int i = 0; i < numSung.Count; i++)
+ {
+ if (numSung[i] < max)
+ mustSing.Add(i);
+ }
+ return mustSing;
+ }
+
+ private static void _AddCombinations(int numPlayer, int playersPerRound, List combinations)
+ {
+ List input = new List(numPlayer);
+ for (int i = 0; i < numPlayer; i++)
+ input.Add(i);
+ CCombinations combs = new CCombinations(input, playersPerRound);
+ combinations.AddRange(combs.Select(combination => new CRound(combination)));
+ combinations.Shuffle();
+ }
+
+ private static CRound _GetMatchingCombination(List playersInRound, List numSung, List combinations)
+ {
+ foreach (CRound round in combinations)
+ {
+ int matching = round.Players.Count(playersInRound.Contains);
+ // A valid round contains only players from playersInRound or all players from playersInRound (and some others)
+ if (matching == round.Players.Count || matching == playersInRound.Count)
+ return round;
+ }
+ // It may happen, that there are only players that already sung against each other. So create a 2nd best option with the most number of players that should sing in it
+ int maxMatching = combinations.Max(c => c.Players.Count(playersInRound.Contains));
+ List nextOptions = combinations.Where(c => c.Players.Count(playersInRound.Contains) == maxMatching).ToList();
+ // And select the combination that minimizes the sum of the number of songs sung (--> favor rounds with players that sung less than others)
+ CRound result = null;
+ int minSung = int.MaxValue;
+ foreach (CRound round in nextOptions)
+ {
+ int curNumSung = round.Players.Sum(pl => numSung[pl]);
+ if (curNumSung < minSung)
+ {
+ minSung = curNumSung;
+ result = round;
+ }
+ }
+ Debug.Assert(result != null);
+ return result;
+ }
+
+ private void _BuildRounds(int numRounds, int numPlayer, int playersPerRound)
+ {
+ // What we want is that every player sung the same amount of songs
+ // and alternate the Players so everyone is Player1 the same amount
+ // So we keep track how many songs each palyer sung
+ List numSung = new List(numPlayer);
+
+ //and which Player had which Position the last time this combination of Players sung
+ SortedDictionary> lastRounds = new SortedDictionary>();
+
+ for (int i = 0; i < numPlayer; i++)
+ numSung.Add(0);
+ List combinations = new List();
+ // Posibly add more rounds than requested if the song count per player is unequal
+ for (int i = 0; i < numRounds * 10; i++)
+ {
+ if (combinations.Count == 0)
+ _AddCombinations(numPlayer, playersPerRound, combinations);
+ List playersInRound = _GetPlayersForRound(numSung);
+ CRound curRound = _GetMatchingCombination(playersInRound, numSung, combinations);
+
+ List sortedPlayers = curRound.Players;
+ sortedPlayers.Sort((x, y) => y.CompareTo(x));
+
+ String key = "";
+
+ foreach (int player in sortedPlayers)
+ {
+ key += player;
+ }
+
+ List lastRound = new List();
+
+ if (lastRounds.ContainsKey(key))
+ {
+
+ lastRounds.TryGetValue(key, out lastRound);
+
+ int first = lastRound.First();
+ lastRound.RemoveAt(0);
+ lastRound.Add(first);
+
+ lastRounds[key] = lastRound;
+
+ for(int k = 0; k < lastRound.Count; k++)
+ {
+ curRound.Players[k] = lastRound[k];
+ }
+ }
+ else
+ {
+ foreach (int player in curRound.Players)
+ {
+ lastRound.Add(player);
+ }
+
+ lastRounds.Add(key, lastRound);
+ }
+
+ foreach (int player in curRound.Players)
+ numSung[player]++;
+ _Rounds.Add(curRound);
+ combinations.Remove(curRound);
+ //Stop if we have enough rounds and all players sung the same amount of songs
+ if (_Rounds.Count >= numRounds && numSung.All(ct => ct == numSung[0]))
+ break;
+ }
+ }
+ }
+
+ public class CRound
+ {
+ public List Players;
+
+ public CRound(List players)
+ {
+ Players = players;
+ }
+ }
+}
\ No newline at end of file
diff --git a/PartyModes/PartyModeChallengeRounds/CPartyModeChallengeRounds.cs b/PartyModes/PartyModeChallengeRounds/CPartyModeChallengeRounds.cs
new file mode 100644
index 00000000..0a7ad89b
--- /dev/null
+++ b/PartyModes/PartyModeChallengeRounds/CPartyModeChallengeRounds.cs
@@ -0,0 +1,563 @@
+#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 .
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using VocaluxeLib.Menu;
+
+[assembly: ComVisible(false)]
+
+namespace VocaluxeLib.PartyModes.ChallengeRounds
+{
+ public class CResultTableRow : IComparable
+ {
+ public int Position;
+ public int PlayerID;
+ public int NumPlayed;
+ public int NumWon;
+ public int NumSingPoints;
+ public int NumGamePoints;
+
+ public int CompareTo(object obj)
+ {
+ var row = obj as CResultTableRow;
+ if (row != null)
+ {
+ int res = row.NumGamePoints.CompareTo(NumGamePoints);
+ if (res == 0)
+ {
+ res = row.NumSingPoints.CompareTo(NumSingPoints);
+ if (res == 0)
+ res = row.NumWon.CompareTo(NumWon);
+ }
+ return res;
+ }
+
+ throw new ArgumentException("object is not a ResultTableRow");
+ }
+ }
+
+ public abstract class CPartyScreenChallengeRounds : CMenuParty
+ {
+ protected new CPartyModeChallengeRounds _PartyMode;
+
+ public override void Init()
+ {
+ base.Init();
+ _PartyMode = (CPartyModeChallengeRounds)base._PartyMode;
+ }
+ }
+
+ // ReSharper disable ClassNeverInstantiated.Global
+ public sealed class CPartyModeChallengeRounds : CPartyMode
+ // ReSharper restore ClassNeverInstantiated.Global
+ {
+ public override int MinMics
+ {
+ get { return 1; }
+ }
+ public override int MaxMics
+ {
+ get { return CBase.Config.GetMaxNumMics(); }
+ }
+ public override int MinPlayers
+ {
+ get { return 1; }
+ }
+ public override int MaxPlayers
+ {
+ get { return 12; }
+ }
+ public override int MinTeams
+ {
+ get { return 1; }
+ }
+ public override int MaxTeams
+ {
+ get { return 1; }
+ }
+ public override int MinPlayersPerTeam
+ {
+ get { return MinPlayers; }
+ }
+ public override int MaxPlayersPerTeam
+ {
+ get { return MaxPlayers; }
+ }
+
+ private enum EStage
+ {
+ Config,
+ Names,
+ Main,
+ Singing
+ }
+
+ public struct SData
+ {
+ public int NumPlayer;
+ public int NumPlayerAtOnce;
+ public int NumRounds;
+ public int NumJokers;
+ public bool RefillJokers;
+ public int[] Jokers;
+ public List ProfileIDs;
+
+ public CChallengeRounds Rounds;
+ public List ResultTable;
+ public int[,] Results;
+
+ public int CurrentRoundNr;
+
+ public int[] CatSongIndices;
+ }
+
+ private struct SStats
+ {
+ public int ProfileID;
+ public int SingPoints;
+ public int GamePoints;
+ public int Won;
+ }
+
+ public SData GameData;
+ private EStage _Stage;
+
+ public CPartyModeChallengeRounds(int id) : base(id)
+ {
+ _ScreenSongOptions.Selection.RandomOnly = false;
+ _ScreenSongOptions.Selection.PartyMode = true;
+ _ScreenSongOptions.Selection.CategoryChangeAllowed = true;
+ _ScreenSongOptions.Selection.NumJokers = new int[] {5, 5};
+ _ScreenSongOptions.Selection.TeamNames = new string[] {"foo", "bar"};
+
+ _ScreenSongOptions.Sorting.SearchString = String.Empty;
+ _ScreenSongOptions.Sorting.SearchActive = false;
+ _ScreenSongOptions.Sorting.DuetOptions = EDuetOptions.NoDuets;
+
+ GameData = new SData {NumPlayer = 4, NumPlayerAtOnce = 2, NumRounds = 12, NumJokers = 5, RefillJokers = true, CurrentRoundNr = 1, ProfileIDs = new List(), CatSongIndices = null, Results = null};
+ }
+
+ public override void SetDefaults()
+ {
+ _Stage = EStage.Config;
+
+ _ScreenSongOptions.Sorting.IgnoreArticles = CBase.Config.GetIgnoreArticles();
+ _ScreenSongOptions.Sorting.SongSorting = CBase.Config.GetSongSorting();
+ _ScreenSongOptions.Sorting.Tabs = EOffOn.TR_CONFIG_OFF;
+ _ScreenSongOptions.Selection.SongIndex = -1;
+
+ if (CBase.Config.GetTabs() == EOffOn.TR_CONFIG_ON && _ScreenSongOptions.Sorting.SongSorting != ESongSorting.TR_CONFIG_NONE)
+ _ScreenSongOptions.Sorting.Tabs = EOffOn.TR_CONFIG_ON;
+
+ GameData.ResultTable = new List();
+ }
+
+ public override bool Init()
+ {
+ if (!base.Init())
+ return false;
+ _Stage = EStage.Config;
+
+ SetDefaults();
+ return true;
+ }
+
+ public override void UpdateGame()
+ {
+ /*
+ if (CBase.Songs.IsInCategory() || _ScreenSongOptions.Sorting.Tabs == EOffOn.TR_CONFIG_OFF)
+ _ScreenSongOptions.Selection.RandomOnly = true;
+ else
+ _ScreenSongOptions.Selection.RandomOnly = false;*/
+ }
+
+ private IMenu _GetNextScreen()
+ {
+ switch (_Stage)
+ {
+ case EStage.Config:
+ return _Screens["CPartyScreenChallengeRoundsConfig"];
+ case EStage.Names:
+ return _Screens["CPartyScreenChallengeRoundsNames"];
+ case EStage.Main:
+ return _Screens["CPartyScreenChallengeRoundsMain"];
+ case EStage.Singing:
+ return CBase.Graphics.GetScreen(EScreen.Song);
+ default:
+ throw new ArgumentException("Invalid stage: " + _Stage);
+ }
+ }
+
+ private void _FadeToScreen()
+ {
+ CBase.Graphics.FadeTo(_GetNextScreen());
+ }
+
+ public void Next()
+ {
+ switch (_Stage)
+ {
+ case EStage.Config:
+ _Stage = EStage.Names;
+ break;
+ case EStage.Names:
+ _Stage = EStage.Main;
+ CBase.Songs.ResetSongSung();
+ GameData.ResultTable = new List();
+ GameData.Rounds = new CChallengeRounds(GameData.NumRounds, GameData.NumPlayer, GameData.NumPlayerAtOnce);
+ GameData.CurrentRoundNr = 1;
+ GameData.Jokers = null;
+ break;
+ case EStage.Main:
+ _Stage = EStage.Singing;
+ _StartNextRound();
+ break;
+ case EStage.Singing:
+ _Stage = EStage.Main;
+ _UpdateScores();
+ break;
+ default:
+ throw new ArgumentException("Invalid stage: " + _Stage);
+ }
+ _FadeToScreen();
+ }
+
+ public void Back()
+ {
+ switch (_Stage)
+ {
+ case EStage.Config:
+ CBase.Graphics.FadeTo(EScreen.Party);
+ return;
+ case EStage.Names:
+ _Stage = EStage.Config;
+ break;
+ case EStage.Main:
+ _Stage = EStage.Names;
+ break;
+ default: // Rest is not allowed
+ throw new ArgumentException("Invalid stage: " + _Stage);
+ }
+ _FadeToScreen();
+ }
+
+ public override IMenu GetStartScreen()
+ {
+ return _Screens["CPartyScreenChallengeRoundsConfig"];
+ }
+
+ public override SScreenSongOptions GetScreenSongOptions()
+ {
+ _ScreenSongOptions.Sorting.SongSorting = CBase.Config.GetSongSorting();
+ _ScreenSongOptions.Sorting.Tabs = CBase.Config.GetTabs();
+ _ScreenSongOptions.Sorting.IgnoreArticles = CBase.Config.GetIgnoreArticles();
+
+ return _ScreenSongOptions;
+ }
+
+ // ReSharper disable RedundantAssignment
+ public override void OnSongChange(int songIndex, ref SScreenSongOptions screenSongOptions)
+ // ReSharper restore RedundantAssignment
+ {
+ _ScreenSongOptions.Selection.SongIndex = -1;
+
+ if (_ScreenSongOptions.Selection.SelectNextRandomSong && songIndex != -1)
+ {
+ _ScreenSongOptions.Selection.SelectNextRandomSong = false;
+ _CreateCatSongIndices();
+
+ if (GameData.CatSongIndices != null)
+ {
+ if (GameData.CatSongIndices[CBase.Songs.GetCurrentCategoryIndex()] == -1)
+ GameData.CatSongIndices[CBase.Songs.GetCurrentCategoryIndex()] = songIndex;
+ }
+ }
+
+ screenSongOptions = _ScreenSongOptions;
+ }
+
+ // ReSharper disable RedundantAssignment
+ public override void OnCategoryChange(int categoryIndex, ref SScreenSongOptions screenSongOptions)
+ // ReSharper restore RedundantAssignment
+ {
+ if (GameData.CatSongIndices != null && categoryIndex != -1)
+ {
+ if (GameData.CatSongIndices[categoryIndex] == -1)
+ _ScreenSongOptions.Selection.SelectNextRandomSong = true;
+ else
+ _ScreenSongOptions.Selection.SongIndex = GameData.CatSongIndices[categoryIndex];
+ }
+
+ if (GameData.CatSongIndices == null && categoryIndex != -1)
+ _ScreenSongOptions.Selection.SelectNextRandomSong = true;
+
+ if (categoryIndex == -1)
+ _ScreenSongOptions.Selection.RandomOnly = false;
+
+ if (_ScreenSongOptions.Sorting.Tabs == EOffOn.TR_CONFIG_OFF || categoryIndex != -1)
+ _ScreenSongOptions.Selection.RandomOnly = true;
+
+ screenSongOptions = _ScreenSongOptions;
+ }
+
+ public override void SetSearchString(string searchString, bool visible)
+ {
+ _ScreenSongOptions.Sorting.SearchString = searchString;
+ _ScreenSongOptions.Sorting.SearchActive = visible;
+ }
+
+ public override void JokerUsed(int teamNr)
+ {
+ if (_ScreenSongOptions.Selection.NumJokers == null)
+ return;
+
+ if (teamNr >= _ScreenSongOptions.Selection.NumJokers.Length)
+ return;
+
+ if (!GameData.RefillJokers)
+ {
+ CRound round = GameData.Rounds[GameData.CurrentRoundNr - 1];
+ GameData.Jokers[round.Players[teamNr]]--;
+ }
+ _ScreenSongOptions.Selection.NumJokers[teamNr]--;
+ _ScreenSongOptions.Selection.RandomOnly = true;
+ _ScreenSongOptions.Selection.CategoryChangeAllowed = false;
+ }
+
+ public override void SongSelected(int songID)
+ {
+ const EGameMode gm = EGameMode.TR_GAMEMODE_NORMAL;
+
+ CBase.Game.Reset();
+ CBase.Game.ClearSongs();
+ CBase.Game.AddSong(songID, gm);
+ CBase.Game.SetNumPlayer(GameData.NumPlayerAtOnce);
+
+ SPlayer[] players = CBase.Game.GetPlayers();
+ if (players == null)
+ return;
+
+ if (players.Length < GameData.NumPlayerAtOnce)
+ return;
+
+ CRound c = GameData.Rounds[GameData.CurrentRoundNr - 1];
+
+ for (int i = 0; i < GameData.NumPlayerAtOnce; i++)
+ {
+ //try to fill with the right data
+ if (c != null)
+ players[i].ProfileID = GameData.ProfileIDs[c.Players[i]];
+ else
+ players[i].ProfileID = -1;
+ }
+
+ CBase.Graphics.FadeTo(EScreen.Sing);
+ }
+
+ public override void LeavingHighscore()
+ {
+ CBase.Songs.AddPartySongSung(CBase.Game.GetSong(0).ID);
+ GameData.CurrentRoundNr++;
+ Next();
+ }
+
+ private void _StartNextRound()
+ {
+ _ScreenSongOptions.Selection.RandomOnly = _ScreenSongOptions.Sorting.Tabs != EOffOn.TR_CONFIG_ON;
+ _ScreenSongOptions.Selection.CategoryChangeAllowed = _ScreenSongOptions.Sorting.Tabs == EOffOn.TR_CONFIG_ON;
+ _SetNumJokers();
+ _SetTeamNames();
+ GameData.CatSongIndices = null;
+ }
+
+ private void _SetNumJokers()
+ {
+ int[] jokers = new int[GameData.NumPlayerAtOnce];
+ if (GameData.RefillJokers)
+ {
+ for (int i = 0; i < jokers.Length; i++)
+ jokers[i] = GameData.NumJokers;
+ }
+ else
+ {
+ if (GameData.Jokers == null)
+ {
+ GameData.Jokers = new int[GameData.NumPlayer];
+ for (int i = 0; i < GameData.ProfileIDs.Count; i++)
+ {
+ GameData.Jokers[i] = GameData.NumJokers;
+ }
+ }
+ CRound round = GameData.Rounds[GameData.CurrentRoundNr - 1];
+ for (int i = 0; i < GameData.NumPlayerAtOnce; i++)
+ {
+ jokers[i] = GameData.Jokers[round.Players[i]];
+ }
+ }
+ _ScreenSongOptions.Selection.NumJokers = jokers;
+ }
+
+ private void _SetTeamNames()
+ {
+ if (GameData.NumPlayerAtOnce < 1 || GameData.ProfileIDs.Count < GameData.NumPlayerAtOnce)
+ {
+ _ScreenSongOptions.Selection.TeamNames = new string[] {"foo", "bar"};
+ return;
+ }
+
+ _ScreenSongOptions.Selection.TeamNames = new string[GameData.NumPlayerAtOnce];
+ CRound c = GameData.Rounds[GameData.CurrentRoundNr - 1];
+
+ for (int i = 0; i < GameData.NumPlayerAtOnce; i++)
+ _ScreenSongOptions.Selection.TeamNames[i] = CBase.Profiles.GetPlayerName(GameData.ProfileIDs[c.Players[i]]);
+ }
+
+ private void _UpdateScores()
+ {
+ if (GameData.ResultTable.Count == 0)
+ {
+ for (int i = 0; i < GameData.NumPlayer; i++)
+ {
+ var row = new CResultTableRow {PlayerID = GameData.ProfileIDs[i], NumPlayed = 0, NumWon = 0, NumSingPoints = 0, NumGamePoints = 0};
+ GameData.ResultTable.Add(row);
+ }
+
+ GameData.Results = new int[GameData.NumRounds,GameData.NumPlayerAtOnce];
+ for (int i = 0; i < GameData.NumRounds; i++)
+ {
+ for (int j = 0; j < GameData.NumPlayerAtOnce; j++)
+ GameData.Results[i, j] = 0;
+ }
+ }
+ SPlayer[] results = CBase.Game.GetPlayers();
+ if (results == null)
+ return;
+
+ if (results.Length < GameData.NumPlayerAtOnce)
+ return;
+
+ for (int j = 0; j < GameData.NumPlayerAtOnce; j++)
+ GameData.Results[GameData.CurrentRoundNr - 2, j] = (int)Math.Round(results[j].Points);
+
+ List points = _GetPointsForPlayer(results);
+
+ for (int i = 0; i < GameData.NumPlayerAtOnce; i++)
+ {
+ int index = -1;
+ for (int j = 0; j < GameData.ResultTable.Count; j++)
+ {
+ if (points[i].ProfileID == GameData.ResultTable[j].PlayerID)
+ {
+ index = j;
+ break;
+ }
+ }
+
+ if (index == -1)
+ continue;
+ CResultTableRow row = GameData.ResultTable[index];
+
+ row.NumPlayed++;
+ row.NumWon += points[i].Won;
+ row.NumSingPoints += points[i].SingPoints;
+ row.NumGamePoints += points[i].GamePoints;
+
+ GameData.ResultTable[index] = row;
+ }
+
+
+ GameData.ResultTable.Sort();
+
+ //Update position-number
+ int pos = 1;
+ int lastPoints = 0;
+ int lastSingPoints = 0;
+ foreach (CResultTableRow resultRow in GameData.ResultTable)
+ {
+ if (lastPoints > resultRow.NumGamePoints || lastSingPoints > resultRow.NumSingPoints)
+ pos++;
+ resultRow.Position = pos;
+ lastPoints = resultRow.NumGamePoints;
+ lastSingPoints = resultRow.NumSingPoints;
+ }
+ }
+
+ private List _GetPointsForPlayer(SPlayer[] results)
+ {
+ var result = new List();
+ for (int i = 0; i < GameData.NumPlayerAtOnce; i++)
+ {
+ var stat = new SStats {ProfileID = results[i].ProfileID, SingPoints = (int)Math.Round(results[i].Points), Won = 0, GamePoints = 0};
+ result.Add(stat);
+ }
+
+ result.Sort((s1, s2) => s1.SingPoints.CompareTo(s2.SingPoints));
+
+ int current = result[result.Count - 1].SingPoints;
+ int points = result.Count;
+ bool wonset = false;
+
+ for (int i = result.Count - 1; i >= 0; i--)
+ {
+ SStats res = result[i];
+
+ if (i < result.Count - 1)
+ {
+ if (current > res.SingPoints)
+ {
+ res.GamePoints = i * 2;
+ wonset = true;
+ points = res.GamePoints;
+ }
+ else
+ {
+ if (!wonset)
+ res.Won = 1;
+ res.GamePoints = points;
+ }
+ }
+ else
+ {
+ res.GamePoints = i * 2;
+ res.Won = 1;
+ }
+
+ current = res.SingPoints;
+
+ result[i] = res;
+ }
+
+
+ return result;
+ }
+
+ private void _CreateCatSongIndices()
+ {
+ if (GameData.CatSongIndices == null && CBase.Songs.GetNumCategories() > 0 && _ScreenSongOptions.Sorting.Tabs == EOffOn.TR_CONFIG_ON)
+ {
+ GameData.CatSongIndices = new int[CBase.Songs.GetNumCategories()];
+ for (int i = 0; i < GameData.CatSongIndices.Length; i++)
+ GameData.CatSongIndices[i] = -1;
+ }
+
+ if (CBase.Songs.GetNumCategories() == 0 || _ScreenSongOptions.Sorting.Tabs == EOffOn.TR_CONFIG_OFF)
+ GameData.CatSongIndices = null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/PartyModes/PartyModeChallengeRounds/CPartyScreenChallengeRoundsConfig.cs b/PartyModes/PartyModeChallengeRounds/CPartyScreenChallengeRoundsConfig.cs
new file mode 100644
index 00000000..3df6418d
--- /dev/null
+++ b/PartyModes/PartyModeChallengeRounds/CPartyScreenChallengeRoundsConfig.cs
@@ -0,0 +1,208 @@
+#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 .
+#endregion
+
+using System;
+using System.Windows.Forms;
+
+namespace VocaluxeLib.PartyModes.ChallengeRounds
+{
+ // ReSharper disable UnusedMember.Global
+ public class CPartyScreenChallengeRoundsConfig : CPartyScreenChallengeRounds
+ // ReSharper restore UnusedMember.Global
+ {
+ // Version number for theme files. Increment it, if you've changed something on the theme files!
+ protected override int _ScreenVersion
+ {
+ get { return 3; }
+ }
+
+ private const string _SelectSlideNumPlayers = "SelectSlideNumPlayers";
+ private const string _SelectSlideNumMics = "SelectSlideNumMics";
+ private const string _SelectSlideNumRounds = "SelectSlideNumRounds";
+ private const string _SelectSlideNumJokers = "SelectSlideNumJokers";
+ private const string _SelectSlideRefillJokers = "SelectSlideRefillJokers";
+ private const string _ButtonNext = "ButtonNext";
+ private const string _ButtonBack = "ButtonBack";
+
+ private const int _MaxNumRounds = 100;
+ private int _RoundSteps = 1;
+
+ public override void Init()
+ {
+ base.Init();
+
+ _ThemeSelectSlides = new string[] { _SelectSlideNumPlayers, _SelectSlideNumMics, _SelectSlideNumRounds, _SelectSlideNumJokers, _SelectSlideRefillJokers };
+ _ThemeButtons = new string[] {_ButtonNext, _ButtonBack};
+ }
+
+ public override bool HandleInput(SKeyEvent keyEvent)
+ {
+ base.HandleInput(keyEvent);
+
+ if (keyEvent.KeyPressed) {}
+ else
+ {
+ switch (keyEvent.Key)
+ {
+ case Keys.Back:
+ case Keys.Escape:
+ _PartyMode.Back();
+ break;
+
+ case Keys.Enter:
+ _UpdateSlides();
+
+ if (_Buttons[_ButtonBack].Selected)
+ _PartyMode.Back();
+
+ if (_Buttons[_ButtonNext].Selected)
+ _PartyMode.Next();
+ break;
+
+ case Keys.Left:
+ _UpdateSlides();
+ break;
+
+ case Keys.Right:
+ _UpdateSlides();
+ break;
+ }
+ }
+ return true;
+ }
+
+ public override bool HandleMouse(SMouseEvent mouseEvent)
+ {
+ base.HandleMouse(mouseEvent);
+
+ if (mouseEvent.LB && _IsMouseOverCurSelection(mouseEvent))
+ {
+ _UpdateSlides();
+ if (_Buttons[_ButtonBack].Selected)
+ _PartyMode.Back();
+
+ if (_Buttons[_ButtonNext].Selected)
+ _PartyMode.Next();
+ }
+
+ if (mouseEvent.RB)
+ _PartyMode.Back();
+
+ return true;
+ }
+
+ public override void OnShow()
+ {
+ base.OnShow();
+
+ _RebuildSlides();
+ }
+
+ public override bool UpdateGame()
+ {
+ return true;
+ }
+
+ private void _RebuildSlides()
+ {
+ // build num player slide (min player ... max player);
+ _SelectSlides[_SelectSlideNumPlayers].Clear();
+ for (int i = _PartyMode.MinPlayers; i <= _PartyMode.MaxPlayers; i++)
+ _SelectSlides[_SelectSlideNumPlayers].AddValue(i.ToString());
+ _SelectSlides[_SelectSlideNumPlayers].SelectedValue = _PartyMode.GameData.NumPlayer.ToString();
+
+ // build num joker slide 1 to 10
+ _SelectSlides[_SelectSlideNumJokers].Clear();
+ for (int i = 1; i <= 10; i++)
+ {
+ _SelectSlides[_SelectSlideNumJokers].AddValue(i.ToString());
+ }
+ _SelectSlides[_SelectSlideNumJokers].SelectedValue = "5";
+
+ //build joker config slide
+ _SelectSlides[_SelectSlideRefillJokers].Clear();
+ _SelectSlides[_SelectSlideRefillJokers].AddValue(CBase.Language.Translate("TR_BUTTON_NO", PartyModeID));
+ _SelectSlides[_SelectSlideRefillJokers].AddValue(CBase.Language.Translate("TR_BUTTON_YES", PartyModeID));
+ _SelectSlides[_SelectSlideRefillJokers].SelectLastValue();
+
+ _UpdateMicsAtOnce();
+ _SetRoundSteps();
+ _UpdateSlideRounds();
+ }
+
+ private void _UpdateSlides()
+ {
+ int player = _PartyMode.GameData.NumPlayer;
+ int mics = _PartyMode.GameData.NumPlayerAtOnce;
+ _PartyMode.GameData.NumPlayer = _SelectSlides[_SelectSlideNumPlayers].Selection + _PartyMode.MinPlayers;
+ _PartyMode.GameData.NumPlayerAtOnce = _SelectSlides[_SelectSlideNumMics].Selection + _PartyMode.MinPlayers;
+ _PartyMode.GameData.NumRounds = (_SelectSlides[_SelectSlideNumRounds].Selection + 1) * _RoundSteps;
+ _PartyMode.GameData.NumJokers = _SelectSlides[_SelectSlideNumJokers].Selection + 1;
+ _PartyMode.GameData.RefillJokers = (_SelectSlides[_SelectSlideRefillJokers].Selection == 1) ? true : false;
+
+ _UpdateMicsAtOnce();
+ _SetRoundSteps();
+
+ if (player != _PartyMode.GameData.NumPlayer || mics != _PartyMode.GameData.NumPlayerAtOnce)
+ {
+ int num = CHelper.CombinationCount(_PartyMode.GameData.NumPlayer, _PartyMode.GameData.NumPlayerAtOnce);
+ while (num > _MaxNumRounds)
+ num -= _RoundSteps;
+ _PartyMode.GameData.NumRounds = num;
+ }
+
+ _UpdateSlideRounds();
+ }
+
+ private void _UpdateMicsAtOnce()
+ {
+ int maxNum = Math.Min(_PartyMode.MaxMics, _PartyMode.GameData.NumPlayer);
+
+ if (_PartyMode.GameData.NumPlayerAtOnce > maxNum)
+ _PartyMode.GameData.NumPlayerAtOnce = maxNum;
+
+ // build mics at once slide
+ _SelectSlides[_SelectSlideNumMics].Clear();
+ for (int i = 1; i <= maxNum; i++)
+ _SelectSlides[_SelectSlideNumMics].AddValue(i.ToString());
+ _SelectSlides[_SelectSlideNumMics].Selection = _PartyMode.GameData.NumPlayerAtOnce - _PartyMode.MinPlayers;
+ }
+
+ private void _UpdateSlideRounds()
+ {
+ // build num rounds slide
+ _SelectSlides[_SelectSlideNumRounds].Clear();
+ for (int i = _RoundSteps; i <= _MaxNumRounds; i += _RoundSteps)
+ _SelectSlides[_SelectSlideNumRounds].AddValue(i.ToString());
+ _SelectSlides[_SelectSlideNumRounds].Selection = _PartyMode.GameData.NumRounds / _RoundSteps - 1;
+ }
+
+ private void _SetRoundSteps()
+ {
+ if (_PartyMode.GameData.NumPlayerAtOnce < 1 || _PartyMode.GameData.NumPlayer < 1 || _PartyMode.GameData.NumPlayerAtOnce > _PartyMode.GameData.NumPlayer)
+ {
+ _RoundSteps = 1;
+ return;
+ }
+
+ int res = _PartyMode.GameData.NumPlayer / _PartyMode.GameData.NumPlayerAtOnce;
+ int mod = _PartyMode.GameData.NumPlayer % _PartyMode.GameData.NumPlayerAtOnce;
+
+ _RoundSteps = mod == 0 ? res : _PartyMode.GameData.NumPlayer;
+ }
+ }
+}
\ No newline at end of file
diff --git a/PartyModes/PartyModeChallengeRounds/CPartyScreenChallengeRoundsMain.cs b/PartyModes/PartyModeChallengeRounds/CPartyScreenChallengeRoundsMain.cs
new file mode 100644
index 00000000..de7c7800
--- /dev/null
+++ b/PartyModes/PartyModeChallengeRounds/CPartyScreenChallengeRoundsMain.cs
@@ -0,0 +1,630 @@
+#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 .
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Windows.Forms;
+using VocaluxeLib.Menu;
+
+namespace VocaluxeLib.PartyModes.ChallengeRounds
+{
+ struct STableRow
+ {
+ public CText Pos;
+ public CText Name;
+ public CText Rounds;
+ public CText Won;
+ public CText SingPoints;
+ public CText GamePoints;
+ }
+
+ class CRoundsTableRow
+ {
+ public CText Number;
+ public List TextPlayer;
+ public List TextScores;
+ }
+
+ // ReSharper disable UnusedMember.Global
+ public class CPartyScreenChallengeRoundsMain : CPartyScreenChallengeRounds
+ // ReSharper restore UnusedMember.Global
+ {
+ // Version number for theme files. Increment it, if you've changed something on the theme files!
+ protected override int _ScreenVersion
+ {
+ get { return 1; }
+ }
+
+ private const string _TextPosition = "TextPosition";
+ private const string _TextPlayerName = "TextPlayerName";
+ private const string _TextNumPlayed = "TextNumPlayed";
+ private const string _TextWon = "TextWon";
+ private const string _TextSingPoints = "TextSingPoints";
+ private const string _TextGamePoints = "TextGamePoints";
+ private const string _TextNextPlayer = "TextNextPlayer";
+ private const string _TextPopupReallyExit = "TextPopupReallyExit";
+ private const string _TextRoundPlayer = "TextRoundPlayer";
+ private const string _TextRoundScore = "TextRoundScore";
+ private const string _TextRoundNumber = "TextRoundNumber";
+ private const string _TextFinishMessage = "TextFinishMessage";
+ private const string _TextFinishPlayerWin = "TextFinishPlayerWin";
+ private const string _TextNextPlayerMessage = "TextNextPlayerMessage";
+
+ private const string _ButtonNextRound = "ButtonNextRound";
+ private const string _ButtonBack = "ButtonBack";
+ private const string _ButtonExit = "ButtonExit";
+ private const string _ButtonPopupYes = "ButtonPopupYes";
+ private const string _ButtonPopupNo = "ButtonPopupNo";
+ private const string _ButtonPlayerScrollUp = "ButtonPlayerScrollUp";
+ private const string _ButtonPlayerScrollDown = "ButtonPlayerScrollDown";
+ private const string _ButtonRoundsScrollUp = "ButtonRoundsScrollUp";
+ private const string _ButtonRoundsScrollDown = "ButtonRoundsScrollDown";
+
+ private const string _StaticPopupBG = "StaticPopupBG";
+ private const string _StaticNextPlayer = "StaticNextPlayer";
+
+ private bool _ExitPopupVisible;
+
+ private List _PlayerTable;
+ private List _RoundsTable;
+
+ private List _NextPlayerTexts;
+ private List _NextPlayerStatics;
+
+ private SRectF _RoundsTableScrollArea;
+ private SRectF _PlayerTableScrollArea;
+ private int _RoundsTableOffset;
+ private int _PlayerTableOffset;
+ private const int _NumPlayerVisible = 10;
+ private int _NumRoundsVisible = 3;
+
+ public override void Init()
+ {
+ base.Init();
+
+ _ThemeTexts = new string[]
+ {
+ _TextPosition, _TextPlayerName, _TextNumPlayed, _TextWon, _TextSingPoints, _TextGamePoints, _TextNextPlayer, _TextPopupReallyExit, _TextRoundNumber,
+ _TextRoundPlayer,
+ _TextRoundScore, _TextFinishMessage, _TextFinishPlayerWin, _TextNextPlayerMessage
+ };
+ _ThemeButtons = new string[]
+ {
+ _ButtonNextRound, _ButtonBack, _ButtonExit, _ButtonPopupYes, _ButtonPopupNo, _ButtonPlayerScrollDown, _ButtonPlayerScrollUp, _ButtonRoundsScrollDown,
+ _ButtonRoundsScrollUp
+ };
+ _ThemeStatics = new string[] {_StaticPopupBG, _StaticNextPlayer};
+ }
+
+ public override void LoadTheme(string xmlPath)
+ {
+ base.LoadTheme(xmlPath);
+
+ _BuildPlayerTable();
+ _CreateRoundsTable();
+ _NextPlayerTexts = new List();
+ _NextPlayerStatics = new List();
+
+ for (int i = 0; i < _PartyMode.MaxPlayers; i++)
+ {
+ _NextPlayerTexts.Add(GetNewText(_Texts[_TextNextPlayer]));
+ _AddText(_NextPlayerTexts[_NextPlayerTexts.Count - 1]);
+ _NextPlayerStatics.Add(GetNewStatic(_Statics[_StaticNextPlayer]));
+ _AddStatic(_NextPlayerStatics[_NextPlayerStatics.Count - 1]);
+ }
+ _Statics[_StaticNextPlayer].Visible = false;
+ }
+
+ public override bool HandleInput(SKeyEvent keyEvent)
+ {
+ base.HandleInput(keyEvent);
+
+ if (keyEvent.KeyPressed) {}
+ else
+ {
+ switch (keyEvent.Key)
+ {
+ case Keys.Back:
+ case Keys.Escape:
+ if (!_ExitPopupVisible)
+ {
+ if (_PartyMode.GameData.CurrentRoundNr == 1)
+ _PartyMode.Back();
+ else
+ _ShowPopup(true);
+ }
+ else
+ _ShowPopup(false);
+ break;
+
+ case Keys.Enter:
+ if (!_ExitPopupVisible)
+ {
+ if (_Buttons[_ButtonNextRound].Selected)
+ _PartyMode.Next();
+ if (_Buttons[_ButtonBack].Selected && _PartyMode.GameData.CurrentRoundNr == 1)
+ _PartyMode.Back();
+ if (_Buttons[_ButtonExit].Selected && _PartyMode.GameData.CurrentRoundNr > 1)
+ _ShowPopup(true);
+ if (_Buttons[_ButtonPlayerScrollUp].Selected)
+ _ScrollPlayerTable(-1);
+ if (_Buttons[_ButtonPlayerScrollDown].Selected)
+ _ScrollPlayerTable(1);
+ if (_Buttons[_ButtonRoundsScrollUp].Selected)
+ _ScrollRoundsTable(-1);
+ if (_Buttons[_ButtonRoundsScrollDown].Selected)
+ _ScrollRoundsTable(1);
+ }
+ else
+ {
+ if (_Buttons[_ButtonPopupYes].Selected)
+ _EndParty();
+ if (_Buttons[_ButtonPopupNo].Selected)
+ _ShowPopup(false);
+ }
+ break;
+ }
+ }
+ return true;
+ }
+
+ public override bool HandleMouse(SMouseEvent mouseEvent)
+ {
+ base.HandleMouse(mouseEvent);
+
+ if (mouseEvent.LB && _IsMouseOverCurSelection(mouseEvent))
+ {
+ if (!_ExitPopupVisible)
+ {
+ if (_Buttons[_ButtonNextRound].Selected)
+ _PartyMode.Next();
+ if (_Buttons[_ButtonBack].Selected && _PartyMode.GameData.CurrentRoundNr == 1)
+ _PartyMode.Back();
+ if (_Buttons[_ButtonExit].Selected && _PartyMode.GameData.CurrentRoundNr > 1)
+ _ShowPopup(true);
+ if (_Buttons[_ButtonPlayerScrollUp].Selected)
+ _ScrollPlayerTable(-1);
+ if (_Buttons[_ButtonPlayerScrollDown].Selected)
+ _ScrollPlayerTable(1);
+ if (_Buttons[_ButtonRoundsScrollUp].Selected)
+ _ScrollRoundsTable(-1);
+ if (_Buttons[_ButtonRoundsScrollDown].Selected)
+ _ScrollRoundsTable(1);
+ }
+ else
+ {
+ if (_Buttons[_ButtonPopupYes].Selected)
+ _EndParty();
+ if (_Buttons[_ButtonPopupNo].Selected)
+ _ShowPopup(false);
+ }
+ }
+
+ if (mouseEvent.RB)
+ {
+ if (!_ExitPopupVisible)
+ {
+ if (_PartyMode.GameData.CurrentRoundNr == 1)
+ _PartyMode.Back();
+ else
+ _ShowPopup(true);
+ }
+ else
+ _ShowPopup(false);
+ }
+
+ if (mouseEvent.Wheel != 0)
+ {
+ if (CHelper.IsInBounds(_RoundsTableScrollArea, mouseEvent))
+ _ScrollRoundsTable(mouseEvent.Wheel);
+ if (CHelper.IsInBounds(_PlayerTableScrollArea, mouseEvent))
+ _ScrollPlayerTable(mouseEvent.Wheel);
+ }
+
+ return true;
+ }
+
+ public override void OnShow()
+ {
+ base.OnShow();
+
+ _PlayerTableOffset = 0;
+ _RoundsTableOffset = 0;
+
+ _UpdatePlayerTable();
+ _UpdateNextPlayerPositions();
+ _UpdateNextPlayerContents();
+ if (_PartyMode.GameData.CurrentRoundNr == 1)
+ _BuildRoundsTable();
+ else
+ _ScrollRoundsTable(_PartyMode.GameData.CurrentRoundNr - 2);
+ _UpdateRoundsTable();
+
+ if (_PartyMode.GameData.CurrentRoundNr == 1)
+ {
+ _Buttons[_ButtonBack].Visible = true;
+ _Buttons[_ButtonExit].Visible = false;
+ }
+ else
+ {
+ _Buttons[_ButtonBack].Visible = false;
+ _Buttons[_ButtonExit].Visible = true;
+ }
+
+ if (_PartyMode.GameData.CurrentRoundNr <= _PartyMode.GameData.Rounds.Count)
+ {
+ _Buttons[_ButtonNextRound].Visible = true;
+ _Texts[_TextFinishMessage].Visible = false;
+ _Texts[_TextFinishPlayerWin].Visible = false;
+ _SelectElement(_Buttons[_ButtonNextRound]);
+ }
+ else
+ {
+ _Buttons[_ButtonNextRound].Visible = false;
+ _Texts[_TextFinishMessage].Visible = true;
+ _Texts[_TextFinishPlayerWin].Visible = true;
+ _Texts[_TextFinishPlayerWin].Text = _GetPlayerWinString();
+ _SelectElement(_Buttons[_ButtonExit]);
+ }
+
+ _ShowPopup(false);
+ }
+
+ public override bool UpdateGame()
+ {
+ return true;
+ }
+
+ private void _EndParty()
+ {
+ CBase.Graphics.FadeTo(EScreen.Party);
+ }
+
+ private void _ShowPopup(bool visible)
+ {
+ _ExitPopupVisible = visible;
+
+ _Statics[_StaticPopupBG].Visible = _ExitPopupVisible;
+ _Texts[_TextPopupReallyExit].Visible = _ExitPopupVisible;
+ _Buttons[_ButtonPopupYes].Visible = _ExitPopupVisible;
+ _Buttons[_ButtonPopupNo].Visible = _ExitPopupVisible;
+
+ if (_ExitPopupVisible)
+ _SelectElement(_Buttons[_ButtonPopupNo]);
+ }
+
+ private void _UpdateNextPlayerPositions()
+ {
+ float x = (float)CBase.Settings.GetRenderW() / 2 -
+ ((_PartyMode.GameData.NumPlayerAtOnce * _Statics[_StaticNextPlayer].Rect.W) + ((_PartyMode.GameData.NumPlayerAtOnce - 1) * 15)) / 2;
+ const float staticY = 590;
+ const float textY = 550;
+ for (int i = 0; i < _PartyMode.GameData.NumPlayerAtOnce; i++)
+ {
+ //static
+ _NextPlayerStatics[i].X = x;
+ _NextPlayerStatics[i].Y = staticY;
+ _NextPlayerStatics[i].Visible = true;
+ //text
+ _NextPlayerTexts[i].X = x + _Statics[_StaticNextPlayer].Rect.W / 2;
+ _NextPlayerTexts[i].Y = textY;
+ _NextPlayerTexts[i].Visible = true;
+
+ x += _Statics[_StaticNextPlayer].Rect.W + 15;
+ }
+ for (int i = _PartyMode.GameData.NumPlayerAtOnce; i < _PartyMode.MaxPlayers; i++)
+ {
+ _NextPlayerStatics[i].Visible = false;
+ _NextPlayerTexts[i].Visible = false;
+ }
+ }
+
+ private void _UpdateNextPlayerContents()
+ {
+ if (_PartyMode.GameData.CurrentRoundNr <= _PartyMode.GameData.Rounds.Count)
+ {
+ _Texts[_TextNextPlayerMessage].Visible = true;
+ for (int i = 0; i < _PartyMode.GameData.NumPlayerAtOnce; i++)
+ {
+ int id = _PartyMode.GameData.ProfileIDs[_PartyMode.GameData.Rounds[_PartyMode.GameData.CurrentRoundNr - 1].Players[i]];
+ _NextPlayerStatics[i].Texture = CBase.Profiles.GetAvatar(id);
+ _NextPlayerTexts[i].Text = CBase.Profiles.GetPlayerName(id);
+ _NextPlayerTexts[i].Color = CBase.Themes.GetPlayerColor(i + 1);
+ }
+ }
+ else
+ {
+ _Texts[_TextNextPlayerMessage].Visible = false;
+ for (int i = 0; i < _PartyMode.GameData.NumPlayerAtOnce; i++)
+ {
+ _NextPlayerStatics[i].Visible = false;
+ _NextPlayerTexts[i].Visible = false;
+ }
+ }
+ }
+
+ private void _CreateRoundsTable()
+ {
+ //Create lists
+ _RoundsTable = new List();
+ for (int i = 0; i < 5; i++)
+ {
+ var rtr = new CRoundsTableRow {TextPlayer = new List(), TextScores = new List()};
+ _RoundsTable.Add(rtr);
+ }
+ //Create statics and texts for rounds
+ foreach (CRoundsTableRow roundRow in _RoundsTable)
+ {
+ //Round-number
+ CText text = GetNewText(_Texts[_TextRoundNumber]);
+ _AddText(text);
+ roundRow.Number = text;
+ for (int row = 0; row < 2; row++)
+ {
+ for (int column = 0; column < 3; column++)
+ {
+ //Player
+ text = GetNewText(_Texts[_TextRoundPlayer]);
+ _AddText(text);
+ roundRow.TextPlayer.Add(text);
+ //Score
+ text = GetNewText(_Texts[_TextRoundScore]);
+ _AddText(text);
+ roundRow.TextScores.Add(text);
+ }
+ }
+ }
+ }
+
+ private void _BuildRoundsTable()
+ {
+ _RoundsTableScrollArea = new SRectF();
+
+ const int numPlayerInOneRow = 3;
+ _NumRoundsVisible = _PartyMode.GameData.NumPlayerAtOnce <= numPlayerInOneRow ? 5 : 3;
+
+ if (_NumRoundsVisible > _PartyMode.GameData.Rounds.Count)
+ _NumRoundsVisible = _PartyMode.GameData.Rounds.Count;
+
+ float numberX = _Texts[_TextRoundNumber].X;
+ float numberY = _Texts[_TextRoundNumber].Y;
+
+ _RoundsTableScrollArea.X = numberX;
+ _RoundsTableScrollArea.Y = numberY;
+ _RoundsTableScrollArea.W = CBase.Settings.GetRenderW() - _Texts[_TextRoundNumber].X - 20;
+
+ float delta = _Texts[_TextRoundNumber].Rect.H;
+
+ //Update statics and texts for rounds
+ foreach (CRoundsTableRow roundRow in _RoundsTable)
+ {
+ //Round-number
+ roundRow.Number.X = numberX;
+ roundRow.Number.Y = numberY;
+ var numInnerRows = (int)Math.Ceiling(_PartyMode.GameData.NumPlayerAtOnce / ((double)numPlayerInOneRow));
+ for (int row = 0; row < numInnerRows; row++)
+ {
+ int num = (row + 1) * numPlayerInOneRow;
+ int numPlayerInThisRow = numPlayerInOneRow;
+ if (num > _PartyMode.GameData.NumPlayerAtOnce)
+ {
+ num = _PartyMode.GameData.NumPlayerAtOnce;
+ numPlayerInThisRow = _PartyMode.GameData.NumPlayerAtOnce - (row * numPlayerInOneRow);
+ }
+ for (int column = row * numPlayerInOneRow; column < num; column++)
+ {
+ //Player
+ float x = numberX + 15 + (CBase.Settings.GetRenderW() - _Texts[_TextRoundNumber].X - 20) / numPlayerInThisRow * (column - row * numPlayerInOneRow) +
+ ((CBase.Settings.GetRenderW() - _Texts[_TextRoundNumber].X - 20) / numPlayerInThisRow) / 2;
+ float maxw = ((CBase.Settings.GetRenderW() - _Texts[_TextRoundNumber].X - 20) / numPlayerInThisRow) / 2 - 5;
+ roundRow.TextPlayer[column].X = x;
+ roundRow.TextPlayer[column].Y = numberY;
+ roundRow.TextPlayer[column].W = maxw;
+ //Score
+ roundRow.TextScores[column].X = x;
+ roundRow.TextScores[column].Y = numberY + delta;
+ roundRow.TextScores[column].W = maxw;
+ }
+ numberY = numberY + 2 * delta;
+ }
+ numberY = numberY + delta / 2;
+ }
+ _RoundsTableScrollArea.H = numberY - _RoundsTableScrollArea.Y;
+ }
+
+ private void _UpdateRoundsTable()
+ {
+ for (int i = 0; i < _RoundsTable.Count; i++)
+ {
+ for (int p = 0; p < _RoundsTable[i].TextPlayer.Count; p++)
+ {
+ if (_PartyMode.GameData.Rounds.Count > i + _RoundsTableOffset && _PartyMode.GameData.Rounds[i + _RoundsTableOffset].Players.Count > p)
+ {
+ _RoundsTable[i].Number.Visible = true;
+ _RoundsTable[i].TextPlayer[p].Visible = true;
+ _RoundsTable[i].TextScores[p].Visible = true;
+ _RoundsTable[i].Number.Text = (i + 1 + _RoundsTableOffset) + ")";
+ _RoundsTable[i].TextPlayer[p].Text =
+ CBase.Profiles.GetPlayerName(_PartyMode.GameData.ProfileIDs[_PartyMode.GameData.Rounds[i + _RoundsTableOffset].Players[p]]);
+ // ReSharper disable ConvertIfStatementToConditionalTernaryExpression
+ if ((_PartyMode.GameData.CurrentRoundNr - 1) > i + _RoundsTableOffset)
+ // ReSharper restore ConvertIfStatementToConditionalTernaryExpression
+ _RoundsTable[i].TextScores[p].Text = _PartyMode.GameData.Results[i + _RoundsTableOffset, p].ToString();
+ else
+ _RoundsTable[i].TextScores[p].Text = "";
+ }
+ else
+ {
+ _RoundsTable[i].TextPlayer[p].Visible = false;
+ _RoundsTable[i].TextScores[p].Visible = false;
+ }
+ }
+ if (_PartyMode.GameData.Rounds.Count < i + _RoundsTableOffset || i + 1 > _NumRoundsVisible)
+ {
+ _RoundsTable[i].Number.Visible = false;
+ for (int p = 0; p < _RoundsTable[i].TextPlayer.Count; p++)
+ {
+ _RoundsTable[i].TextPlayer[p].Visible = false;
+ _RoundsTable[i].TextScores[p].Visible = false;
+ }
+ }
+ }
+
+ _Buttons[_ButtonRoundsScrollUp].Visible = _RoundsTableOffset > 0;
+ _Buttons[_ButtonRoundsScrollDown].Visible = _PartyMode.GameData.Rounds.Count - _NumRoundsVisible - _RoundsTableOffset > 0;
+ }
+
+ private void _BuildPlayerTable()
+ {
+ _PlayerTableScrollArea = new SRectF {X = _Texts[_TextPosition].X, Y = _Texts[_TextPosition].Y, W = _Texts[_TextGamePoints].X - _Texts[_TextPosition].X};
+
+ _PlayerTable = new List();
+ float delta = _Texts[_TextPosition].Rect.H * 1.2f;
+
+ float h = 0;
+
+ for (int i = 0; i < 10; i++)
+ {
+ var row = new STableRow
+ {
+ Pos = GetNewText(_Texts[_TextPosition]),
+ Name = GetNewText(_Texts[_TextPlayerName]),
+ Rounds = GetNewText(_Texts[_TextNumPlayed]),
+ Won = GetNewText(_Texts[_TextWon]),
+ SingPoints = GetNewText(_Texts[_TextSingPoints]),
+ GamePoints = GetNewText(_Texts[_TextGamePoints])
+ };
+
+ row.Pos.Y += delta * (i + 1);
+ row.Name.Y += delta * (i + 1);
+ row.Rounds.Y += delta * (i + 1);
+ row.Won.Y += delta * (i + 1);
+ row.SingPoints.Y += delta * (i + 1);
+ row.GamePoints.Y += delta * (i + 1);
+
+ row.Pos.Text = (i + 1) + ".";
+
+ row.Pos.Visible = false;
+ row.Name.Visible = false;
+ row.Rounds.Visible = false;
+ row.Won.Visible = false;
+ row.SingPoints.Visible = false;
+ row.GamePoints.Visible = false;
+
+ _AddText(row.Pos);
+ _AddText(row.Name);
+ _AddText(row.Rounds);
+ _AddText(row.Won);
+ _AddText(row.SingPoints);
+ _AddText(row.GamePoints);
+
+ _PlayerTable.Add(row);
+
+ h = delta * (i + 1);
+ }
+ _PlayerTableScrollArea.H = h + delta;
+ }
+
+ private void _UpdatePlayerTable()
+ {
+ for (int i = 0; i < _PlayerTable.Count; i++)
+ {
+ STableRow row = _PlayerTable[i];
+
+ if (i + _PlayerTableOffset < _PartyMode.GameData.ResultTable.Count)
+ {
+ row.Pos.Visible = true;
+ row.Name.Visible = true;
+ row.Rounds.Visible = true;
+ row.Won.Visible = true;
+ row.SingPoints.Visible = true;
+ row.GamePoints.Visible = true;
+
+ row.Pos.Text = _PartyMode.GameData.ResultTable[i + _PlayerTableOffset].Position + ".";
+ row.Name.Text = CBase.Profiles.GetPlayerName(_PartyMode.GameData.ResultTable[i + _PlayerTableOffset].PlayerID);
+ row.Rounds.Text = _PartyMode.GameData.ResultTable[i + _PlayerTableOffset].NumPlayed.ToString();
+ row.Won.Text = _PartyMode.GameData.ResultTable[i + _PlayerTableOffset].NumWon.ToString();
+ row.SingPoints.Text = _PartyMode.GameData.ResultTable[i + _PlayerTableOffset].NumSingPoints.ToString();
+ row.GamePoints.Text = _PartyMode.GameData.ResultTable[i + _PlayerTableOffset].NumGamePoints.ToString();
+ }
+ else
+ {
+ row.Pos.Visible = false;
+ row.Name.Visible = false;
+ row.Rounds.Visible = false;
+ row.Won.Visible = false;
+ row.SingPoints.Visible = false;
+ row.GamePoints.Visible = false;
+ }
+ }
+
+ _Buttons[_ButtonPlayerScrollUp].Visible = _PlayerTableOffset > 0;
+ _Buttons[_ButtonPlayerScrollDown].Visible = _PartyMode.GameData.ProfileIDs.Count - _NumPlayerVisible - _PlayerTableOffset > 0;
+ }
+
+ private void _ScrollPlayerTable(int offset)
+ {
+ if (_PartyMode.GameData.ProfileIDs.Count <= _NumPlayerVisible)
+ _PlayerTableOffset = 0;
+ else if (offset < 0 && _PlayerTableOffset + offset >= 0)
+ _PlayerTableOffset += offset;
+ else if (offset < 0 && _PlayerTableOffset + offset < 0)
+ _PlayerTableOffset = 0;
+ else if (offset > 0 && _PlayerTableOffset + offset <= _PartyMode.GameData.ProfileIDs.Count - _NumPlayerVisible)
+ _PlayerTableOffset += offset;
+ else if (offset > 0 && _PlayerTableOffset + offset > _PartyMode.GameData.ProfileIDs.Count - _NumPlayerVisible)
+ _PlayerTableOffset = _PartyMode.GameData.ProfileIDs.Count - _NumPlayerVisible;
+
+ _UpdatePlayerTable();
+ }
+
+ private void _ScrollRoundsTable(int offset)
+ {
+ if (_PartyMode.GameData.Rounds.Count <= _NumRoundsVisible)
+ _RoundsTableOffset = 0;
+ else if (offset < 0 && _RoundsTableOffset + offset >= 0)
+ _RoundsTableOffset += offset;
+ else if (offset < 0 && _RoundsTableOffset + offset < 0)
+ _RoundsTableOffset = 0;
+ else if (offset > 0 && _RoundsTableOffset + offset <= _PartyMode.GameData.Rounds.Count - _NumRoundsVisible)
+ _RoundsTableOffset += offset;
+ else if (offset > 0 && _RoundsTableOffset + offset > _PartyMode.GameData.Rounds.Count - _NumRoundsVisible)
+ _RoundsTableOffset = _PartyMode.GameData.Rounds.Count - _NumRoundsVisible;
+
+ _UpdateRoundsTable();
+ }
+
+ private string _GetPlayerWinString()
+ {
+ string s = "";
+
+ for (int i = 0; i < _PartyMode.GameData.ResultTable.Count; i++)
+ {
+ if (_PartyMode.GameData.ResultTable[i].Position == 1)
+ {
+ if (i > 0)
+ s += ", ";
+ s += CBase.Profiles.GetPlayerName(_PartyMode.GameData.ResultTable[i].PlayerID);
+ }
+ else
+ break;
+ }
+
+ return s;
+ }
+ }
+}
\ No newline at end of file
diff --git a/PartyModes/PartyModeChallengeRounds/CPartyScreenChallengeRoundsNames.cs b/PartyModes/PartyModeChallengeRounds/CPartyScreenChallengeRoundsNames.cs
new file mode 100644
index 00000000..006c29cc
--- /dev/null
+++ b/PartyModes/PartyModeChallengeRounds/CPartyScreenChallengeRoundsNames.cs
@@ -0,0 +1,67 @@
+#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 .
+#endregion
+
+using System.Collections.Generic;
+using VocaluxeLib.Menu;
+
+namespace VocaluxeLib.PartyModes.ChallengeRounds
+{
+ // ReSharper disable UnusedMember.Global
+ public class CPartyScreenChallengeRoundsNames : CMenuPartyNameSelection
+ // ReSharper restore UnusedMember.Global
+ {
+ // Version number for theme files. Increment it, if you've changed something on the theme files!
+ protected override int _ScreenVersion
+ {
+ get { return 1; }
+ }
+
+ private new CPartyModeChallengeRounds _PartyMode;
+
+ public override void Init()
+ {
+ base.Init();
+ _PartyMode = (CPartyModeChallengeRounds)base._PartyMode;
+ _AllowChangePlayerNum = false;
+ }
+
+ public override void OnShow()
+ {
+ base.OnShow();
+ SetPartyModeData(_PartyMode.GameData.NumPlayer);
+ while (_PartyMode.GameData.ProfileIDs.Count > _NumPlayer)
+ _PartyMode.GameData.ProfileIDs.RemoveAt(_PartyMode.GameData.ProfileIDs.Count - 1);
+
+ List[] ids = new List[] {_PartyMode.GameData.ProfileIDs};
+ SetPartyModeProfiles(ids);
+ }
+
+ public override void Back()
+ {
+ if (_TeamList.Length == 1)
+ _PartyMode.GameData.ProfileIDs = _TeamList[0];
+ _PartyMode.Back();
+ }
+
+ public override void Next()
+ {
+ if (_TeamList.Length == 1)
+ _PartyMode.GameData.ProfileIDs = _TeamList[0];
+ _PartyMode.Next();
+ }
+ }
+}
\ No newline at end of file
diff --git a/PartyModes/PartyModeChallengeRounds/GlobalSuppressions.cs b/PartyModes/PartyModeChallengeRounds/GlobalSuppressions.cs
new file mode 100644
index 00000000..e661ff03
Binary files /dev/null and b/PartyModes/PartyModeChallengeRounds/GlobalSuppressions.cs differ
diff --git a/PartyModes/PartyModeChallengeRounds/PartyModeChallengeRounds.csproj b/PartyModes/PartyModeChallengeRounds/PartyModeChallengeRounds.csproj
new file mode 100644
index 00000000..32dca0fd
--- /dev/null
+++ b/PartyModes/PartyModeChallengeRounds/PartyModeChallengeRounds.csproj
@@ -0,0 +1,71 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}
+ Library
+ Properties
+ VocaluxeLib.PartyModes.ChallengeRounds
+ ChallengeRounds
+ v4.0
+ 512
+ Client
+
+
+ true
+ full
+ false
+ bin\Debug\
+ TRACE;DEBUG;WIN
+ prompt
+ 4
+ x64
+
+
+ pdbonly
+ true
+ bin\
+ WIN
+ prompt
+ 4
+ Off
+ false
+ x64
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {d2b6ddef-e0e1-4ddf-a73a-e6acef5c95ec}
+ VocaluxeLib
+
+
+
+
+
+
+
+ if exist "$(SolutionDir)Output\PartyModes\$(TargetName)\Code" rd "$(SolutionDir)Output\PartyModes\$(TargetName)\Code" /S /Q
+cd $(SolutionDir)Partymodes\
+xcopy "$(ProjectDir)*.cs" "$(SolutionDir)Output\PartyModes\$(TargetName)\Code\" /EXCLUDE:Excludes.txt /I /Y
+
+
+
\ No newline at end of file
diff --git a/PitchTracker/bin/Release.x64/PitchTracker.iobj b/PitchTracker/bin/Release.x64/PitchTracker.iobj
new file mode 100644
index 00000000..7f72cee9
Binary files /dev/null and b/PitchTracker/bin/Release.x64/PitchTracker.iobj differ
diff --git a/PitchTracker/bin/Release.x64/PitchTracker.ipdb b/PitchTracker/bin/Release.x64/PitchTracker.ipdb
new file mode 100644
index 00000000..741f420c
Binary files /dev/null and b/PitchTracker/bin/Release.x64/PitchTracker.ipdb differ
diff --git a/Vocaluxe.VC.db b/Vocaluxe.VC.db
new file mode 100644
index 00000000..e88f32f5
Binary files /dev/null and b/Vocaluxe.VC.db differ
diff --git a/Vocaluxe.sln b/Vocaluxe.sln
index 3a32f864..edf10174 100644
--- a/Vocaluxe.sln
+++ b/Vocaluxe.sln
@@ -1,11 +1,13 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-VisualStudioVersion = 12.0.31101.0
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Vocaluxe", "Vocaluxe\Vocaluxe.csproj", "{2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}"
ProjectSection(ProjectDependencies) = postProject
{55F89808-4E79-4FFE-BC13-48258913F5C9} = {55F89808-4E79-4FFE-BC13-48258913F5C9}
{6F3E1874-F28A-40E9-AFBD-31934D593678} = {6F3E1874-F28A-40E9-AFBD-31934D593678}
{6F3E1874-F28A-40E9-AFBD-31934D593679} = {6F3E1874-F28A-40E9-AFBD-31934D593679}
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE} = {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}
{D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC} = {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}
{5A4053F1-5AD5-441F-B254-D97A088127B6} = {5A4053F1-5AD5-441F-B254-D97A088127B6}
{54A48AF7-515C-4EDD-B395-2BFFA096050A} = {54A48AF7-515C-4EDD-B395-2BFFA096050A}
@@ -30,176 +32,399 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
Vocaluxe.testsettings = Vocaluxe.testsettings
EndProjectSection
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PartyModeChallengeRounds", "PartyModes\PartyModeChallengeRounds\PartyModeChallengeRounds.csproj", "{AB4194D5-3B86-4915-8417-83D3AC2B6DFE}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ DebugLinux|Any CPU = DebugLinux|Any CPU
DebugLinux|x64 = DebugLinux|x64
DebugLinux|x86 = DebugLinux|x86
+ DebugWin|Any CPU = DebugWin|Any CPU
DebugWin|x64 = DebugWin|x64
DebugWin|x86 = DebugWin|x86
+ InstallerWin|Any CPU = InstallerWin|Any CPU
InstallerWin|x64 = InstallerWin|x64
InstallerWin|x86 = InstallerWin|x86
+ Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ ReleaseLinux|Any CPU = ReleaseLinux|Any CPU
ReleaseLinux|x64 = ReleaseLinux|x64
ReleaseLinux|x86 = ReleaseLinux|x86
+ ReleaseWin|Any CPU = ReleaseWin|Any CPU
ReleaseWin|x64 = ReleaseWin|x64
ReleaseWin|x86 = ReleaseWin|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.Debug|Any CPU.ActiveCfg = ReleaseWin|x86
+ {2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.Debug|Any CPU.Build.0 = ReleaseWin|x86
+ {2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.Debug|x64.ActiveCfg = DebugWin|x64
+ {2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.Debug|x64.Build.0 = DebugWin|x64
+ {2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.Debug|x86.ActiveCfg = DebugWin|x86
+ {2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.Debug|x86.Build.0 = DebugWin|x86
+ {2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.DebugLinux|Any CPU.ActiveCfg = DebugLinux|x86
{2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.DebugLinux|x64.ActiveCfg = DebugLinux|x64
{2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.DebugLinux|x64.Build.0 = DebugLinux|x64
{2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.DebugLinux|x86.ActiveCfg = DebugLinux|x86
{2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.DebugLinux|x86.Build.0 = DebugLinux|x86
+ {2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.DebugWin|Any CPU.ActiveCfg = DebugWin|x86
{2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.DebugWin|x64.ActiveCfg = DebugWin|x64
{2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.DebugWin|x64.Build.0 = DebugWin|x64
{2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.DebugWin|x86.ActiveCfg = DebugWin|x86
{2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.DebugWin|x86.Build.0 = DebugWin|x86
+ {2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.InstallerWin|Any CPU.ActiveCfg = InstallerWin|x86
{2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.InstallerWin|x64.ActiveCfg = InstallerWin|x64
{2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.InstallerWin|x64.Build.0 = InstallerWin|x64
{2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.InstallerWin|x86.ActiveCfg = InstallerWin|x86
{2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.InstallerWin|x86.Build.0 = InstallerWin|x86
+ {2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.Release|Any CPU.ActiveCfg = ReleaseWin|x86
+ {2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.Release|Any CPU.Build.0 = ReleaseWin|x86
+ {2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.Release|x64.ActiveCfg = ReleaseWin|x64
+ {2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.Release|x64.Build.0 = ReleaseWin|x64
+ {2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.Release|x86.ActiveCfg = ReleaseWin|x86
+ {2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.Release|x86.Build.0 = ReleaseWin|x86
+ {2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.ReleaseLinux|Any CPU.ActiveCfg = ReleaseLinux|x86
{2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.ReleaseLinux|x64.ActiveCfg = ReleaseLinux|x64
{2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.ReleaseLinux|x64.Build.0 = ReleaseLinux|x64
{2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.ReleaseLinux|x86.ActiveCfg = ReleaseLinux|x86
{2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.ReleaseLinux|x86.Build.0 = ReleaseLinux|x86
+ {2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.ReleaseWin|Any CPU.ActiveCfg = ReleaseWin|x86
{2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.ReleaseWin|x64.ActiveCfg = ReleaseWin|x64
{2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.ReleaseWin|x64.Build.0 = ReleaseWin|x64
{2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.ReleaseWin|x86.ActiveCfg = ReleaseWin|x86
{2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}.ReleaseWin|x86.Build.0 = ReleaseWin|x86
+ {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.Debug|Any CPU.ActiveCfg = DebugWin|Any CPU
+ {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.Debug|Any CPU.Build.0 = DebugWin|Any CPU
+ {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.Debug|x64.ActiveCfg = DebugWin|Any CPU
+ {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.Debug|x64.Build.0 = DebugWin|Any CPU
+ {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.Debug|x86.ActiveCfg = DebugWin|Any CPU
+ {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.Debug|x86.Build.0 = DebugWin|Any CPU
+ {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.DebugLinux|Any CPU.ActiveCfg = DebugLinux|Any CPU
+ {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.DebugLinux|Any CPU.Build.0 = DebugLinux|Any CPU
{D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.DebugLinux|x64.ActiveCfg = DebugLinux|Any CPU
{D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.DebugLinux|x64.Build.0 = DebugLinux|Any CPU
{D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.DebugLinux|x86.ActiveCfg = DebugLinux|Any CPU
{D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.DebugLinux|x86.Build.0 = DebugLinux|Any CPU
+ {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.DebugWin|Any CPU.ActiveCfg = DebugWin|Any CPU
+ {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.DebugWin|Any CPU.Build.0 = DebugWin|Any CPU
{D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.DebugWin|x64.ActiveCfg = DebugWin|Any CPU
{D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.DebugWin|x64.Build.0 = DebugWin|Any CPU
{D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.DebugWin|x86.ActiveCfg = DebugWin|Any CPU
{D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.DebugWin|x86.Build.0 = DebugWin|Any CPU
+ {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.InstallerWin|Any CPU.ActiveCfg = InstallerWin|Any CPU
+ {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.InstallerWin|Any CPU.Build.0 = InstallerWin|Any CPU
{D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.InstallerWin|x64.ActiveCfg = InstallerWin|Any CPU
{D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.InstallerWin|x64.Build.0 = InstallerWin|Any CPU
{D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.InstallerWin|x86.ActiveCfg = InstallerWin|Any CPU
{D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.InstallerWin|x86.Build.0 = InstallerWin|Any CPU
+ {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.Release|Any CPU.ActiveCfg = ReleaseWin|Any CPU
+ {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.Release|Any CPU.Build.0 = ReleaseWin|Any CPU
+ {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.Release|x64.ActiveCfg = ReleaseWin|Any CPU
+ {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.Release|x64.Build.0 = ReleaseWin|Any CPU
+ {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.Release|x86.ActiveCfg = ReleaseWin|Any CPU
+ {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.Release|x86.Build.0 = ReleaseWin|Any CPU
+ {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.ReleaseLinux|Any CPU.ActiveCfg = ReleaseLinux|Any CPU
+ {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.ReleaseLinux|Any CPU.Build.0 = ReleaseLinux|Any CPU
{D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.ReleaseLinux|x64.ActiveCfg = ReleaseLinux|Any CPU
{D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.ReleaseLinux|x64.Build.0 = ReleaseLinux|Any CPU
{D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.ReleaseLinux|x86.ActiveCfg = ReleaseLinux|Any CPU
{D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.ReleaseLinux|x86.Build.0 = ReleaseLinux|Any CPU
+ {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.ReleaseWin|Any CPU.ActiveCfg = ReleaseWin|Any CPU
+ {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.ReleaseWin|Any CPU.Build.0 = ReleaseWin|Any CPU
{D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.ReleaseWin|x64.ActiveCfg = ReleaseWin|Any CPU
{D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.ReleaseWin|x64.Build.0 = ReleaseWin|Any CPU
{D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.ReleaseWin|x86.ActiveCfg = ReleaseWin|Any CPU
{D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}.ReleaseWin|x86.Build.0 = ReleaseWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593679}.Debug|Any CPU.ActiveCfg = DebugWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593679}.Debug|Any CPU.Build.0 = DebugWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593679}.Debug|x64.ActiveCfg = DebugWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593679}.Debug|x64.Build.0 = DebugWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593679}.Debug|x86.ActiveCfg = DebugWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593679}.Debug|x86.Build.0 = DebugWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593679}.DebugLinux|Any CPU.ActiveCfg = DebugLinux|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593679}.DebugLinux|Any CPU.Build.0 = DebugLinux|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593679}.DebugLinux|x64.ActiveCfg = DebugLinux|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593679}.DebugLinux|x64.Build.0 = DebugLinux|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593679}.DebugLinux|x86.ActiveCfg = DebugLinux|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593679}.DebugLinux|x86.Build.0 = DebugLinux|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593679}.DebugWin|Any CPU.ActiveCfg = DebugWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593679}.DebugWin|Any CPU.Build.0 = DebugWin|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593679}.DebugWin|x64.ActiveCfg = DebugWin|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593679}.DebugWin|x64.Build.0 = DebugWin|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593679}.DebugWin|x86.ActiveCfg = DebugWin|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593679}.DebugWin|x86.Build.0 = DebugWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593679}.InstallerWin|Any CPU.ActiveCfg = InstallerWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593679}.InstallerWin|Any CPU.Build.0 = InstallerWin|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593679}.InstallerWin|x64.ActiveCfg = InstallerWin|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593679}.InstallerWin|x64.Build.0 = InstallerWin|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593679}.InstallerWin|x86.ActiveCfg = InstallerWin|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593679}.InstallerWin|x86.Build.0 = InstallerWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593679}.Release|Any CPU.ActiveCfg = ReleaseWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593679}.Release|Any CPU.Build.0 = ReleaseWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593679}.Release|x64.ActiveCfg = ReleaseWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593679}.Release|x64.Build.0 = ReleaseWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593679}.Release|x86.ActiveCfg = ReleaseWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593679}.Release|x86.Build.0 = ReleaseWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593679}.ReleaseLinux|Any CPU.ActiveCfg = ReleaseLinux|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593679}.ReleaseLinux|Any CPU.Build.0 = ReleaseLinux|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593679}.ReleaseLinux|x64.ActiveCfg = ReleaseLinux|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593679}.ReleaseLinux|x64.Build.0 = ReleaseLinux|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593679}.ReleaseLinux|x86.ActiveCfg = ReleaseLinux|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593679}.ReleaseLinux|x86.Build.0 = ReleaseLinux|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593679}.ReleaseWin|Any CPU.ActiveCfg = ReleaseWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593679}.ReleaseWin|Any CPU.Build.0 = ReleaseWin|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593679}.ReleaseWin|x64.ActiveCfg = ReleaseWin|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593679}.ReleaseWin|x64.Build.0 = ReleaseWin|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593679}.ReleaseWin|x86.ActiveCfg = ReleaseWin|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593679}.ReleaseWin|x86.Build.0 = ReleaseWin|Any CPU
+ {5A4053F1-5AD5-441F-B254-D97A088127B6}.Debug|Any CPU.ActiveCfg = DebugWin|Any CPU
+ {5A4053F1-5AD5-441F-B254-D97A088127B6}.Debug|Any CPU.Build.0 = DebugWin|Any CPU
+ {5A4053F1-5AD5-441F-B254-D97A088127B6}.Debug|x64.ActiveCfg = DebugWin|Any CPU
+ {5A4053F1-5AD5-441F-B254-D97A088127B6}.Debug|x64.Build.0 = DebugWin|Any CPU
+ {5A4053F1-5AD5-441F-B254-D97A088127B6}.Debug|x86.ActiveCfg = DebugWin|Any CPU
+ {5A4053F1-5AD5-441F-B254-D97A088127B6}.Debug|x86.Build.0 = DebugWin|Any CPU
+ {5A4053F1-5AD5-441F-B254-D97A088127B6}.DebugLinux|Any CPU.ActiveCfg = DebugLinux|Any CPU
+ {5A4053F1-5AD5-441F-B254-D97A088127B6}.DebugLinux|Any CPU.Build.0 = DebugLinux|Any CPU
{5A4053F1-5AD5-441F-B254-D97A088127B6}.DebugLinux|x64.ActiveCfg = DebugLinux|Any CPU
{5A4053F1-5AD5-441F-B254-D97A088127B6}.DebugLinux|x64.Build.0 = DebugLinux|Any CPU
{5A4053F1-5AD5-441F-B254-D97A088127B6}.DebugLinux|x86.ActiveCfg = DebugLinux|Any CPU
{5A4053F1-5AD5-441F-B254-D97A088127B6}.DebugLinux|x86.Build.0 = DebugLinux|Any CPU
+ {5A4053F1-5AD5-441F-B254-D97A088127B6}.DebugWin|Any CPU.ActiveCfg = DebugWin|Any CPU
+ {5A4053F1-5AD5-441F-B254-D97A088127B6}.DebugWin|Any CPU.Build.0 = DebugWin|Any CPU
{5A4053F1-5AD5-441F-B254-D97A088127B6}.DebugWin|x64.ActiveCfg = DebugWin|Any CPU
{5A4053F1-5AD5-441F-B254-D97A088127B6}.DebugWin|x64.Build.0 = DebugWin|Any CPU
{5A4053F1-5AD5-441F-B254-D97A088127B6}.DebugWin|x86.ActiveCfg = DebugWin|Any CPU
{5A4053F1-5AD5-441F-B254-D97A088127B6}.DebugWin|x86.Build.0 = DebugWin|Any CPU
+ {5A4053F1-5AD5-441F-B254-D97A088127B6}.InstallerWin|Any CPU.ActiveCfg = InstallerWin|Any CPU
+ {5A4053F1-5AD5-441F-B254-D97A088127B6}.InstallerWin|Any CPU.Build.0 = InstallerWin|Any CPU
{5A4053F1-5AD5-441F-B254-D97A088127B6}.InstallerWin|x64.ActiveCfg = InstallerWin|Any CPU
{5A4053F1-5AD5-441F-B254-D97A088127B6}.InstallerWin|x64.Build.0 = InstallerWin|Any CPU
{5A4053F1-5AD5-441F-B254-D97A088127B6}.InstallerWin|x86.ActiveCfg = InstallerWin|Any CPU
{5A4053F1-5AD5-441F-B254-D97A088127B6}.InstallerWin|x86.Build.0 = InstallerWin|Any CPU
+ {5A4053F1-5AD5-441F-B254-D97A088127B6}.Release|Any CPU.ActiveCfg = ReleaseWin|Any CPU
+ {5A4053F1-5AD5-441F-B254-D97A088127B6}.Release|Any CPU.Build.0 = ReleaseWin|Any CPU
+ {5A4053F1-5AD5-441F-B254-D97A088127B6}.Release|x64.ActiveCfg = ReleaseWin|Any CPU
+ {5A4053F1-5AD5-441F-B254-D97A088127B6}.Release|x64.Build.0 = ReleaseWin|Any CPU
+ {5A4053F1-5AD5-441F-B254-D97A088127B6}.Release|x86.ActiveCfg = ReleaseWin|Any CPU
+ {5A4053F1-5AD5-441F-B254-D97A088127B6}.Release|x86.Build.0 = ReleaseWin|Any CPU
+ {5A4053F1-5AD5-441F-B254-D97A088127B6}.ReleaseLinux|Any CPU.ActiveCfg = ReleaseLinux|Any CPU
+ {5A4053F1-5AD5-441F-B254-D97A088127B6}.ReleaseLinux|Any CPU.Build.0 = ReleaseLinux|Any CPU
{5A4053F1-5AD5-441F-B254-D97A088127B6}.ReleaseLinux|x64.ActiveCfg = ReleaseLinux|Any CPU
{5A4053F1-5AD5-441F-B254-D97A088127B6}.ReleaseLinux|x64.Build.0 = ReleaseLinux|Any CPU
{5A4053F1-5AD5-441F-B254-D97A088127B6}.ReleaseLinux|x86.ActiveCfg = ReleaseLinux|Any CPU
{5A4053F1-5AD5-441F-B254-D97A088127B6}.ReleaseLinux|x86.Build.0 = ReleaseLinux|Any CPU
+ {5A4053F1-5AD5-441F-B254-D97A088127B6}.ReleaseWin|Any CPU.ActiveCfg = ReleaseWin|Any CPU
+ {5A4053F1-5AD5-441F-B254-D97A088127B6}.ReleaseWin|Any CPU.Build.0 = ReleaseWin|Any CPU
{5A4053F1-5AD5-441F-B254-D97A088127B6}.ReleaseWin|x64.ActiveCfg = ReleaseWin|Any CPU
{5A4053F1-5AD5-441F-B254-D97A088127B6}.ReleaseWin|x64.Build.0 = ReleaseWin|Any CPU
+ {5A4053F1-5AD5-441F-B254-D97A088127B6}.ReleaseWin|x64.Deploy.0 = ReleaseWin|Any CPU
{5A4053F1-5AD5-441F-B254-D97A088127B6}.ReleaseWin|x86.ActiveCfg = ReleaseWin|Any CPU
{5A4053F1-5AD5-441F-B254-D97A088127B6}.ReleaseWin|x86.Build.0 = ReleaseWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593678}.Debug|Any CPU.ActiveCfg = DebugWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593678}.Debug|Any CPU.Build.0 = DebugWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593678}.Debug|x64.ActiveCfg = DebugWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593678}.Debug|x64.Build.0 = DebugWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593678}.Debug|x86.ActiveCfg = DebugWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593678}.Debug|x86.Build.0 = DebugWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593678}.DebugLinux|Any CPU.ActiveCfg = DebugLinux|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593678}.DebugLinux|Any CPU.Build.0 = DebugLinux|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593678}.DebugLinux|x64.ActiveCfg = DebugLinux|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593678}.DebugLinux|x64.Build.0 = DebugLinux|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593678}.DebugLinux|x86.ActiveCfg = DebugLinux|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593678}.DebugLinux|x86.Build.0 = DebugLinux|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593678}.DebugWin|Any CPU.ActiveCfg = DebugWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593678}.DebugWin|Any CPU.Build.0 = DebugWin|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593678}.DebugWin|x64.ActiveCfg = DebugWin|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593678}.DebugWin|x64.Build.0 = DebugWin|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593678}.DebugWin|x86.ActiveCfg = DebugWin|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593678}.DebugWin|x86.Build.0 = DebugWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593678}.InstallerWin|Any CPU.ActiveCfg = InstallerWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593678}.InstallerWin|Any CPU.Build.0 = InstallerWin|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593678}.InstallerWin|x64.ActiveCfg = InstallerWin|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593678}.InstallerWin|x64.Build.0 = InstallerWin|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593678}.InstallerWin|x86.ActiveCfg = InstallerWin|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593678}.InstallerWin|x86.Build.0 = InstallerWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593678}.Release|Any CPU.ActiveCfg = ReleaseWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593678}.Release|Any CPU.Build.0 = ReleaseWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593678}.Release|x64.ActiveCfg = ReleaseWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593678}.Release|x64.Build.0 = ReleaseWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593678}.Release|x86.ActiveCfg = ReleaseWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593678}.Release|x86.Build.0 = ReleaseWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593678}.ReleaseLinux|Any CPU.ActiveCfg = ReleaseLinux|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593678}.ReleaseLinux|Any CPU.Build.0 = ReleaseLinux|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593678}.ReleaseLinux|x64.ActiveCfg = ReleaseLinux|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593678}.ReleaseLinux|x64.Build.0 = ReleaseLinux|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593678}.ReleaseLinux|x86.ActiveCfg = ReleaseLinux|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593678}.ReleaseLinux|x86.Build.0 = ReleaseLinux|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593678}.ReleaseWin|Any CPU.ActiveCfg = ReleaseWin|Any CPU
+ {6F3E1874-F28A-40E9-AFBD-31934D593678}.ReleaseWin|Any CPU.Build.0 = ReleaseWin|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593678}.ReleaseWin|x64.ActiveCfg = ReleaseWin|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593678}.ReleaseWin|x64.Build.0 = ReleaseWin|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593678}.ReleaseWin|x86.ActiveCfg = ReleaseWin|Any CPU
{6F3E1874-F28A-40E9-AFBD-31934D593678}.ReleaseWin|x86.Build.0 = ReleaseWin|Any CPU
+ {55F89808-4E79-4FFE-BC13-48258913F5C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {55F89808-4E79-4FFE-BC13-48258913F5C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {55F89808-4E79-4FFE-BC13-48258913F5C9}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {55F89808-4E79-4FFE-BC13-48258913F5C9}.Debug|x64.Build.0 = Debug|Any CPU
+ {55F89808-4E79-4FFE-BC13-48258913F5C9}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {55F89808-4E79-4FFE-BC13-48258913F5C9}.Debug|x86.Build.0 = Debug|Any CPU
+ {55F89808-4E79-4FFE-BC13-48258913F5C9}.DebugLinux|Any CPU.ActiveCfg = Debug|Any CPU
+ {55F89808-4E79-4FFE-BC13-48258913F5C9}.DebugLinux|Any CPU.Build.0 = Debug|Any CPU
{55F89808-4E79-4FFE-BC13-48258913F5C9}.DebugLinux|x64.ActiveCfg = Debug|Any CPU
{55F89808-4E79-4FFE-BC13-48258913F5C9}.DebugLinux|x86.ActiveCfg = Debug|Any CPU
+ {55F89808-4E79-4FFE-BC13-48258913F5C9}.DebugWin|Any CPU.ActiveCfg = Debug|Any CPU
+ {55F89808-4E79-4FFE-BC13-48258913F5C9}.DebugWin|Any CPU.Build.0 = Debug|Any CPU
{55F89808-4E79-4FFE-BC13-48258913F5C9}.DebugWin|x64.ActiveCfg = Debug|Any CPU
{55F89808-4E79-4FFE-BC13-48258913F5C9}.DebugWin|x64.Build.0 = Debug|Any CPU
{55F89808-4E79-4FFE-BC13-48258913F5C9}.DebugWin|x86.ActiveCfg = Debug|Any CPU
{55F89808-4E79-4FFE-BC13-48258913F5C9}.DebugWin|x86.Build.0 = Debug|Any CPU
+ {55F89808-4E79-4FFE-BC13-48258913F5C9}.InstallerWin|Any CPU.ActiveCfg = Release|Any CPU
+ {55F89808-4E79-4FFE-BC13-48258913F5C9}.InstallerWin|Any CPU.Build.0 = Release|Any CPU
{55F89808-4E79-4FFE-BC13-48258913F5C9}.InstallerWin|x64.ActiveCfg = Release|Any CPU
{55F89808-4E79-4FFE-BC13-48258913F5C9}.InstallerWin|x64.Build.0 = Release|Any CPU
{55F89808-4E79-4FFE-BC13-48258913F5C9}.InstallerWin|x86.ActiveCfg = Release|Any CPU
{55F89808-4E79-4FFE-BC13-48258913F5C9}.InstallerWin|x86.Build.0 = Release|Any CPU
+ {55F89808-4E79-4FFE-BC13-48258913F5C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {55F89808-4E79-4FFE-BC13-48258913F5C9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {55F89808-4E79-4FFE-BC13-48258913F5C9}.Release|x64.ActiveCfg = Release|Any CPU
+ {55F89808-4E79-4FFE-BC13-48258913F5C9}.Release|x64.Build.0 = Release|Any CPU
+ {55F89808-4E79-4FFE-BC13-48258913F5C9}.Release|x86.ActiveCfg = Release|Any CPU
+ {55F89808-4E79-4FFE-BC13-48258913F5C9}.Release|x86.Build.0 = Release|Any CPU
+ {55F89808-4E79-4FFE-BC13-48258913F5C9}.ReleaseLinux|Any CPU.ActiveCfg = Release|Any CPU
+ {55F89808-4E79-4FFE-BC13-48258913F5C9}.ReleaseLinux|Any CPU.Build.0 = Release|Any CPU
{55F89808-4E79-4FFE-BC13-48258913F5C9}.ReleaseLinux|x64.ActiveCfg = Release|Any CPU
{55F89808-4E79-4FFE-BC13-48258913F5C9}.ReleaseLinux|x86.ActiveCfg = Release|Any CPU
+ {55F89808-4E79-4FFE-BC13-48258913F5C9}.ReleaseWin|Any CPU.ActiveCfg = Release|Any CPU
+ {55F89808-4E79-4FFE-BC13-48258913F5C9}.ReleaseWin|Any CPU.Build.0 = Release|Any CPU
{55F89808-4E79-4FFE-BC13-48258913F5C9}.ReleaseWin|x64.ActiveCfg = Release|Any CPU
{55F89808-4E79-4FFE-BC13-48258913F5C9}.ReleaseWin|x64.Build.0 = Release|Any CPU
{55F89808-4E79-4FFE-BC13-48258913F5C9}.ReleaseWin|x86.ActiveCfg = Release|Any CPU
{55F89808-4E79-4FFE-BC13-48258913F5C9}.ReleaseWin|x86.Build.0 = Release|Any CPU
+ {54A48AF7-515C-4EDD-B395-2BFFA096050A}.Debug|Any CPU.ActiveCfg = Debug|Win32
+ {54A48AF7-515C-4EDD-B395-2BFFA096050A}.Debug|x64.ActiveCfg = Debug|x64
+ {54A48AF7-515C-4EDD-B395-2BFFA096050A}.Debug|x64.Build.0 = Debug|x64
+ {54A48AF7-515C-4EDD-B395-2BFFA096050A}.Debug|x86.ActiveCfg = Debug|Win32
+ {54A48AF7-515C-4EDD-B395-2BFFA096050A}.Debug|x86.Build.0 = Debug|Win32
+ {54A48AF7-515C-4EDD-B395-2BFFA096050A}.DebugLinux|Any CPU.ActiveCfg = Release|Win32
+ {54A48AF7-515C-4EDD-B395-2BFFA096050A}.DebugLinux|Any CPU.Build.0 = Release|Win32
{54A48AF7-515C-4EDD-B395-2BFFA096050A}.DebugLinux|x64.ActiveCfg = Debug|x64
{54A48AF7-515C-4EDD-B395-2BFFA096050A}.DebugLinux|x64.Build.0 = Debug|x64
{54A48AF7-515C-4EDD-B395-2BFFA096050A}.DebugLinux|x86.ActiveCfg = Debug|Win32
{54A48AF7-515C-4EDD-B395-2BFFA096050A}.DebugLinux|x86.Build.0 = Debug|Win32
+ {54A48AF7-515C-4EDD-B395-2BFFA096050A}.DebugWin|Any CPU.ActiveCfg = Release|Win32
+ {54A48AF7-515C-4EDD-B395-2BFFA096050A}.DebugWin|Any CPU.Build.0 = Release|Win32
{54A48AF7-515C-4EDD-B395-2BFFA096050A}.DebugWin|x64.ActiveCfg = Debug|x64
{54A48AF7-515C-4EDD-B395-2BFFA096050A}.DebugWin|x64.Build.0 = Debug|x64
{54A48AF7-515C-4EDD-B395-2BFFA096050A}.DebugWin|x86.ActiveCfg = Debug|Win32
{54A48AF7-515C-4EDD-B395-2BFFA096050A}.DebugWin|x86.Build.0 = Debug|Win32
+ {54A48AF7-515C-4EDD-B395-2BFFA096050A}.InstallerWin|Any CPU.ActiveCfg = Release|Win32
+ {54A48AF7-515C-4EDD-B395-2BFFA096050A}.InstallerWin|Any CPU.Build.0 = Release|Win32
{54A48AF7-515C-4EDD-B395-2BFFA096050A}.InstallerWin|x64.ActiveCfg = Release|x64
{54A48AF7-515C-4EDD-B395-2BFFA096050A}.InstallerWin|x64.Build.0 = Release|x64
{54A48AF7-515C-4EDD-B395-2BFFA096050A}.InstallerWin|x86.ActiveCfg = Release|Win32
{54A48AF7-515C-4EDD-B395-2BFFA096050A}.InstallerWin|x86.Build.0 = Release|Win32
+ {54A48AF7-515C-4EDD-B395-2BFFA096050A}.Release|Any CPU.ActiveCfg = Release|Win32
+ {54A48AF7-515C-4EDD-B395-2BFFA096050A}.Release|x64.ActiveCfg = Release|x64
+ {54A48AF7-515C-4EDD-B395-2BFFA096050A}.Release|x64.Build.0 = Release|x64
+ {54A48AF7-515C-4EDD-B395-2BFFA096050A}.Release|x86.ActiveCfg = Release|Win32
+ {54A48AF7-515C-4EDD-B395-2BFFA096050A}.Release|x86.Build.0 = Release|Win32
+ {54A48AF7-515C-4EDD-B395-2BFFA096050A}.ReleaseLinux|Any CPU.ActiveCfg = Release|Win32
+ {54A48AF7-515C-4EDD-B395-2BFFA096050A}.ReleaseLinux|Any CPU.Build.0 = Release|Win32
{54A48AF7-515C-4EDD-B395-2BFFA096050A}.ReleaseLinux|x64.ActiveCfg = Release|x64
{54A48AF7-515C-4EDD-B395-2BFFA096050A}.ReleaseLinux|x64.Build.0 = Release|x64
{54A48AF7-515C-4EDD-B395-2BFFA096050A}.ReleaseLinux|x86.ActiveCfg = Release|Win32
{54A48AF7-515C-4EDD-B395-2BFFA096050A}.ReleaseLinux|x86.Build.0 = Release|Win32
+ {54A48AF7-515C-4EDD-B395-2BFFA096050A}.ReleaseWin|Any CPU.ActiveCfg = Release|Win32
+ {54A48AF7-515C-4EDD-B395-2BFFA096050A}.ReleaseWin|Any CPU.Build.0 = Release|Win32
{54A48AF7-515C-4EDD-B395-2BFFA096050A}.ReleaseWin|x64.ActiveCfg = Release|x64
{54A48AF7-515C-4EDD-B395-2BFFA096050A}.ReleaseWin|x64.Build.0 = Release|x64
{54A48AF7-515C-4EDD-B395-2BFFA096050A}.ReleaseWin|x86.ActiveCfg = Release|Win32
{54A48AF7-515C-4EDD-B395-2BFFA096050A}.ReleaseWin|x86.Build.0 = Release|Win32
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.Debug|x64.ActiveCfg = Debug|x64
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.Debug|x64.Build.0 = Debug|x64
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.Debug|x86.ActiveCfg = Debug|x86
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.Debug|x86.Build.0 = Debug|x86
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.DebugLinux|Any CPU.ActiveCfg = Release|x86
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.DebugLinux|Any CPU.Build.0 = Release|x86
{93356718-3A0B-4784-AAE1-215065BFFC66}.DebugLinux|x64.ActiveCfg = Debug|x64
{93356718-3A0B-4784-AAE1-215065BFFC66}.DebugLinux|x64.Build.0 = Debug|x64
{93356718-3A0B-4784-AAE1-215065BFFC66}.DebugLinux|x86.ActiveCfg = Debug|x86
{93356718-3A0B-4784-AAE1-215065BFFC66}.DebugLinux|x86.Build.0 = Debug|x86
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.DebugWin|Any CPU.ActiveCfg = Release|x86
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.DebugWin|Any CPU.Build.0 = Release|x86
{93356718-3A0B-4784-AAE1-215065BFFC66}.DebugWin|x64.ActiveCfg = Debug|x64
{93356718-3A0B-4784-AAE1-215065BFFC66}.DebugWin|x64.Build.0 = Debug|x64
{93356718-3A0B-4784-AAE1-215065BFFC66}.DebugWin|x86.ActiveCfg = Debug|x86
{93356718-3A0B-4784-AAE1-215065BFFC66}.DebugWin|x86.Build.0 = Debug|x86
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.InstallerWin|Any CPU.ActiveCfg = Release|x86
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.InstallerWin|Any CPU.Build.0 = Release|x86
{93356718-3A0B-4784-AAE1-215065BFFC66}.InstallerWin|x64.ActiveCfg = Release|x64
{93356718-3A0B-4784-AAE1-215065BFFC66}.InstallerWin|x64.Build.0 = Release|x64
{93356718-3A0B-4784-AAE1-215065BFFC66}.InstallerWin|x86.ActiveCfg = Release|x86
{93356718-3A0B-4784-AAE1-215065BFFC66}.InstallerWin|x86.Build.0 = Release|x86
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.Release|Any CPU.ActiveCfg = Release|x86
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.Release|x64.ActiveCfg = Release|x64
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.Release|x64.Build.0 = Release|x64
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.Release|x86.ActiveCfg = Release|x86
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.Release|x86.Build.0 = Release|x86
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.ReleaseLinux|Any CPU.ActiveCfg = Release|x86
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.ReleaseLinux|Any CPU.Build.0 = Release|x86
{93356718-3A0B-4784-AAE1-215065BFFC66}.ReleaseLinux|x64.ActiveCfg = Release|x64
{93356718-3A0B-4784-AAE1-215065BFFC66}.ReleaseLinux|x64.Build.0 = Release|x64
{93356718-3A0B-4784-AAE1-215065BFFC66}.ReleaseLinux|x86.ActiveCfg = Release|x86
{93356718-3A0B-4784-AAE1-215065BFFC66}.ReleaseLinux|x86.Build.0 = Release|x86
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.ReleaseWin|Any CPU.ActiveCfg = Release|x86
+ {93356718-3A0B-4784-AAE1-215065BFFC66}.ReleaseWin|Any CPU.Build.0 = Release|x86
{93356718-3A0B-4784-AAE1-215065BFFC66}.ReleaseWin|x64.ActiveCfg = Release|x64
{93356718-3A0B-4784-AAE1-215065BFFC66}.ReleaseWin|x64.Build.0 = Release|x64
{93356718-3A0B-4784-AAE1-215065BFFC66}.ReleaseWin|x86.ActiveCfg = Release|x86
{93356718-3A0B-4784-AAE1-215065BFFC66}.ReleaseWin|x86.Build.0 = Release|x86
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.Debug|x64.Build.0 = Debug|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.Debug|x86.Build.0 = Debug|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.DebugLinux|Any CPU.ActiveCfg = Debug|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.DebugLinux|Any CPU.Build.0 = Debug|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.DebugLinux|x64.ActiveCfg = Debug|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.DebugLinux|x64.Build.0 = Debug|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.DebugLinux|x86.ActiveCfg = Debug|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.DebugLinux|x86.Build.0 = Debug|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.DebugWin|Any CPU.ActiveCfg = Debug|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.DebugWin|Any CPU.Build.0 = Debug|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.DebugWin|x64.ActiveCfg = Debug|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.DebugWin|x64.Build.0 = Debug|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.DebugWin|x86.ActiveCfg = Debug|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.DebugWin|x86.Build.0 = Debug|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.InstallerWin|Any CPU.ActiveCfg = Release|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.InstallerWin|Any CPU.Build.0 = Release|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.InstallerWin|x64.ActiveCfg = Release|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.InstallerWin|x64.Build.0 = Release|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.InstallerWin|x86.ActiveCfg = Release|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.InstallerWin|x86.Build.0 = Release|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.Release|x64.ActiveCfg = Release|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.Release|x64.Build.0 = Release|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.Release|x86.ActiveCfg = Release|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.Release|x86.Build.0 = Release|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.ReleaseLinux|Any CPU.ActiveCfg = Release|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.ReleaseLinux|Any CPU.Build.0 = Release|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.ReleaseLinux|x64.ActiveCfg = Release|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.ReleaseLinux|x64.Build.0 = Release|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.ReleaseLinux|x86.ActiveCfg = Release|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.ReleaseLinux|x86.Build.0 = Release|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.ReleaseWin|Any CPU.ActiveCfg = Release|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.ReleaseWin|Any CPU.Build.0 = Release|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.ReleaseWin|x64.ActiveCfg = Release|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.ReleaseWin|x64.Build.0 = Release|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.ReleaseWin|x86.ActiveCfg = Release|Any CPU
+ {AB4194D5-3B86-4915-8417-83D3AC2B6DFE}.ReleaseWin|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Vocaluxe/Base/CMain.cs b/Vocaluxe/Base/CMain.cs
index 3a131649..12f96b04 100644
--- a/Vocaluxe/Base/CMain.cs
+++ b/Vocaluxe/Base/CMain.cs
@@ -923,6 +923,11 @@ namespace Vocaluxe.Base
{
return CDataBase.GetDataBaseSongInfos(artist, title, out numPlayed, out dateAdded, out highscoreID);
}
+
+ public List LoadScore(int songID, EGameMode gameMode, EHighscoreStyle style)
+ {
+ return CDataBase.LoadScore(songID, gameMode, style);
+ }
}
class CBcontrollers : IControllers
diff --git a/VocaluxeLib/Enums.cs b/VocaluxeLib/Enums.cs
index 39e8399f..e9b3b9d8 100644
--- a/VocaluxeLib/Enums.cs
+++ b/VocaluxeLib/Enums.cs
@@ -201,6 +201,7 @@ namespace VocaluxeLib
{
// ReSharper disable InconsistentNaming
TR_CONFIG_LIST, // list of covers and artist - title
+ TR_CONFIG_LIST_RECORD,
//TR_CONFIG_DREIDEL, //as in ultrastar deluxe
TR_CONFIG_TILE_BOARD, //chessboard like
//TR_CONFIG_BOOK //for playlists
diff --git a/VocaluxeLib/IBasic.cs b/VocaluxeLib/IBasic.cs
index 0e35883e..11e1a297 100644
--- a/VocaluxeLib/IBasic.cs
+++ b/VocaluxeLib/IBasic.cs
@@ -296,6 +296,7 @@ namespace VocaluxeLib
{
bool GetCover(string fileName, ref CTextureRef texture, int coverSize);
bool GetDataBaseSongInfos(string artist, string title, out int numPlayed, out DateTime dateAdded, out int highscoreID);
+ List LoadScore(int songID, EGameMode gameMode, EHighscoreStyle style);
}
public interface IControllers
diff --git a/VocaluxeLib/Menu/SongMenu/CSongMenuFactory.cs b/VocaluxeLib/Menu/SongMenu/CSongMenuFactory.cs
index fe4bbb73..714847fe 100644
--- a/VocaluxeLib/Menu/SongMenu/CSongMenuFactory.cs
+++ b/VocaluxeLib/Menu/SongMenu/CSongMenuFactory.cs
@@ -28,9 +28,15 @@ namespace VocaluxeLib.Menu.SongMenu
case ESongMenu.TR_CONFIG_LIST:
return new CSongMenuList(theme, partyModeID);
- //case ESongMenu.TR_CONFIG_DREIDEL:
- // _SongMenu = new CSongMenuDreidel();
- // break;
+ //case ESongMenu.TR_CONFIG_DREIDEL:
+ // _SongMenu = new CSongMenuDreidel();
+ // break;
+ case ESongMenu.TR_CONFIG_LIST_RECORD:
+ return new CSongMenuListRecord(theme, partyModeID);
+
+ //case ESongMenu.TR_CONFIG_DREIDEL:
+ // _SongMenu = new CSongMenuDreidel();
+ // break;
case ESongMenu.TR_CONFIG_TILE_BOARD:
return new CSongMenuTileBoard(theme, partyModeID);
diff --git a/VocaluxeLib/Menu/SongMenu/CSongMenuFramework.cs b/VocaluxeLib/Menu/SongMenu/CSongMenuFramework.cs
index 21e66baf..d5ecc332 100644
--- a/VocaluxeLib/Menu/SongMenu/CSongMenuFramework.cs
+++ b/VocaluxeLib/Menu/SongMenu/CSongMenuFramework.cs
@@ -40,7 +40,9 @@ namespace VocaluxeLib.Menu.SongMenu
//public SThemeSongMenuBook songMenuBook;
//public SThemeSongMenuDreidel songMenuDreidel;
public SThemeSongMenuList SongMenuList;
+ public SThemeSongMenuListRecord SongMenuListRecord;
public SThemeSongMenuTileBoard SongMenuTileBoard;
+
}
public struct SThemeSongMenuList
{
@@ -74,6 +76,40 @@ namespace VocaluxeLib.Menu.SongMenu
public SThemeStatic StaticMedleyTagIcon;
}
+ public struct SThemeSongMenuListRecord
+ {
+ ///
+ /// Number of visible songs in list
+ ///
+ public int ListLength;
+
+ ///
+ /// Space between tiles horizontal
+ ///
+ public float SpaceW;
+
+ ///
+ /// Space between tiles vertical
+ ///
+ public float SpaceH;
+
+ public SRectF TileRect;
+ public SRectF TileRectSmall;
+
+ public SRectF TileRectRecord;
+
+ public SThemeText TextArtist;
+ public SThemeText TextTitle;
+ public SThemeText TextSongLength;
+
+ public SThemeStatic StaticCoverBig;
+ public SThemeStatic StaticTextBG;
+ public SThemeStatic StaticDuetIcon;
+ public SThemeStatic StaticVideoIcon;
+ public SThemeStatic StaticMedleyCalcIcon;
+ public SThemeStatic StaticMedleyTagIcon;
+ }
+
public struct SThemeSongMenuTileBoard
{
diff --git a/VocaluxeLib/Menu/SongMenu/CSongMenuListRecord.cs b/VocaluxeLib/Menu/SongMenu/CSongMenuListRecord.cs
new file mode 100644
index 00000000..e260274b
--- /dev/null
+++ b/VocaluxeLib/Menu/SongMenu/CSongMenuListRecord.cs
@@ -0,0 +1,769 @@
+#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 .
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+using VocaluxeLib;
+using VocaluxeLib.Draw;
+using VocaluxeLib.PartyModes;
+using VocaluxeLib.Songs;
+using VocaluxeLib.Xml;
+
+namespace VocaluxeLib.Menu.SongMenu
+{
+ class CSongMenuListRecord : CSongMenuFramework
+ {
+ private SRectF _ScrollRect;
+ private List _Tiles;
+ private List _Texts;
+ private List _Records;
+ private readonly CStatic _CoverBig;
+ private readonly CStatic _TextBG;
+ private readonly CStatic _DuetIcon;
+ private readonly CStatic _VideoIcon;
+ private readonly CStatic _MedleyCalcIcon;
+ private readonly CStatic _MedleyTagIcon;
+
+ private CTextureRef _CoverBigBGTexture;
+ private CTextureRef _CoverBGTexture;
+
+ private readonly CText _Artist;
+ private readonly CText _Title;
+ private readonly CText _SongLength;
+
+ private float _SpaceW;
+ private float _SpaceH;
+
+ private int _TileW;
+ private int _TileH;
+
+ private int _ListLength;
+ private float _ListTextWidth;
+
+ // Offset is the song or categoryNr of the tile in the left upper corner
+ private int _Offset;
+
+ private float _Length = -1f;
+ private int _LastKnownElements;
+ private int _LastKnownCategory;
+
+ private bool _MouseWasInRect;
+
+ private readonly List _SubElements = new List();
+
+ public override float SelectedTileZoomFactor
+ {
+ get { return 1.2f; }
+ }
+
+ protected override int _SelectionNr
+ {
+ set
+ {
+ int max = CBase.Songs.IsInCategory() ? CBase.Songs.GetNumSongsVisible() : CBase.Songs.GetNumCategories();
+ base._SelectionNr = value.Clamp(-1, max - 1, true);
+ //Update list in case we scrolled
+ _UpdateList();
+
+ _UpdateTileSelection();
+ }
+ }
+
+ public override bool SmallView
+ {
+ set
+ {
+ if (SmallView == value)
+ return;
+ base.SmallView = value;
+ _InitTiles();
+ _UpdateList(true);
+ _UpdateTileSelection();
+ }
+ }
+
+ protected override int _PreviewNr
+ {
+ set
+ {
+ if (value == base._PreviewNr)
+ {
+ if (!CBase.BackgroundMusic.IsPlaying() && value != -1)
+ CBase.BackgroundMusic.Play();
+ return;
+ }
+ base._PreviewNr = value;
+ _UpdatePreview();
+ }
+ }
+
+ public CSongMenuListRecord(SThemeSongMenu theme, int partyModeID) : base(theme, partyModeID)
+ {
+ _ListLength = _Theme.SongMenuListRecord.ListLength;
+ _SpaceW = _Theme.SongMenuListRecord.SpaceW;
+ _SpaceH = _Theme.SongMenuListRecord.SpaceH;
+ _Artist = new CText(_Theme.SongMenuListRecord.TextArtist, _PartyModeID);
+ _Title = new CText(_Theme.SongMenuListRecord.TextTitle, _PartyModeID);
+ _SongLength = new CText(_Theme.SongMenuListRecord.TextSongLength, _PartyModeID);
+ _CoverBig = new CStatic(_Theme.SongMenuListRecord.StaticCoverBig, _PartyModeID);
+ _TextBG = new CStatic(_Theme.SongMenuListRecord.StaticTextBG, _PartyModeID);
+ _DuetIcon = new CStatic(_Theme.SongMenuListRecord.StaticDuetIcon, _PartyModeID);
+ _VideoIcon = new CStatic(_Theme.SongMenuListRecord.StaticVideoIcon, _PartyModeID);
+ _MedleyCalcIcon = new CStatic(_Theme.SongMenuListRecord.StaticMedleyCalcIcon, _PartyModeID);
+ _MedleyTagIcon = new CStatic(_Theme.SongMenuListRecord.StaticMedleyTagIcon, _PartyModeID);
+ _SubElements.AddRange(new IMenuElement[] {_Artist, _Title, _SongLength, _DuetIcon, _VideoIcon, _MedleyCalcIcon, _MedleyTagIcon});
+ }
+
+ public override bool LoadTheme(string xmlPath, string elementName, CXmlReader xmlReader)
+ {
+ string item = xmlPath + "/" + elementName;
+
+ bool themeLoaded = true;
+ themeLoaded &= base.LoadTheme(xmlPath, elementName, xmlReader);
+
+
+ themeLoaded &= _Artist.LoadTheme(item + "/SongMenuListRecord", "TextArtist", xmlReader);
+ themeLoaded &= _Title.LoadTheme(item + "/SongMenuListRecord", "TextTitle", xmlReader);
+ themeLoaded &= _SongLength.LoadTheme(item + "/SongMenuListRecord", "TextSongLength", xmlReader);
+
+ themeLoaded &= _CoverBig.LoadTheme(item + "/SongMenuListRecord", "StaticCoverBig", xmlReader);
+ themeLoaded &= _TextBG.LoadTheme(item + "/SongMenuListRecord", "StaticTextBG", xmlReader);
+ themeLoaded &= _DuetIcon.LoadTheme(item + "/SongMenuListRecord", "StaticDuetIcon", xmlReader);
+ themeLoaded &= _VideoIcon.LoadTheme(item + "/SongMenuListRecord", "StaticVideoIcon", xmlReader);
+ themeLoaded &= _MedleyCalcIcon.LoadTheme(item + "/SongMenuListRecord", "StaticMedleyCalcIcon", xmlReader);
+ themeLoaded &= _MedleyTagIcon.LoadTheme(item + "/SongMenuListRecord", "StaticMedleyTagIcon", xmlReader);
+
+ if (themeLoaded)
+ {
+ _Theme.Name = elementName;
+
+ _ReadSubTheme();
+ _SubElements.Clear();
+ _SubElements.AddRange(new IMenuElement[] { _Artist, _Title, _SongLength, _DuetIcon, _VideoIcon, _MedleyCalcIcon, _MedleyTagIcon });
+ LoadSkin();
+ Init();
+ }
+
+ return themeLoaded;
+ }
+
+ private void _ReadSubTheme()
+ {
+ _Theme.SongMenuListRecord.TextArtist = (SThemeText)_Artist.GetTheme();
+ _Theme.SongMenuListRecord.TextSongLength = (SThemeText)_SongLength.GetTheme();
+ _Theme.SongMenuListRecord.TextTitle = (SThemeText)_Title.GetTheme();
+ _Theme.SongMenuListRecord.StaticCoverBig = (SThemeStatic)_CoverBig.GetTheme();
+ _Theme.SongMenuListRecord.StaticDuetIcon = (SThemeStatic)_DuetIcon.GetTheme();
+ _Theme.SongMenuListRecord.StaticMedleyCalcIcon = (SThemeStatic)_MedleyCalcIcon.GetTheme();
+ _Theme.SongMenuListRecord.StaticMedleyTagIcon = (SThemeStatic)_MedleyTagIcon.GetTheme();
+ _Theme.SongMenuListRecord.StaticTextBG = (SThemeStatic)_TextBG.GetTheme();
+ _Theme.SongMenuListRecord.StaticVideoIcon = (SThemeStatic)_VideoIcon.GetTheme();
+ }
+
+ public override object GetTheme()
+ {
+ _ReadSubTheme();
+ return base.GetTheme();
+ }
+
+ public override void Init()
+ {
+ base.Init();
+
+ _PreviewNr = -1;
+ _InitTiles();
+ _InitRecords();
+ }
+
+ private void _InitTiles()
+ {
+ MaxRect = SmallView ? _Theme.SongMenuListRecord.TileRectSmall : _Theme.SongMenuListRecord.TileRect;
+
+ _ListTextWidth = MaxRect.W - _ListTextWidth;
+
+ _TileW = (int)((MaxRect.H - _SpaceH * (_ListLength - 1)) / _ListLength);
+ _TileH = _TileW;
+
+ _CoverBGTexture = CBase.Themes.GetSkinTexture(_Theme.CoverBackground, _PartyModeID);
+ _CoverBigBGTexture = CBase.Themes.GetSkinTexture(_Theme.CoverBigBackground, _PartyModeID);
+
+ //Create cover tiles
+ _Tiles = new List();
+ _Texts = new List();
+
+ for (int i = 0; i < _ListLength; i++)
+ {
+ //Create Cover
+ var rect = new SRectF(Rect.X + (_TileW + _SpaceW), Rect.Y + i * (_TileH + _SpaceH), _TileW, _TileH, Rect.Z);
+ var tile = new CStatic(_PartyModeID, _CoverBGTexture, _Color, rect);
+ _Tiles.Add(tile);
+
+ //Create text for Artist
+ var textRect = new SRectF(MaxRect.X + 2 * (_TileW + _SpaceW), Rect.Y + i * (_TileH + _SpaceH), _ListTextWidth, _TileH, Rect.Z);
+ CText text = new CText(textRect.X, textRect.Y, textRect.Z,
+ textRect.H / 2, textRect.W, EAlignment.Left, EStyle.Normal,
+ "Normal", _Artist.Color, "");
+ text.MaxRect = new SRectF(text.MaxRect.X, text.MaxRect.Y, MaxRect.W + MaxRect.X - text.Rect.X - 5f, text.MaxRect.H / 2, text.MaxRect.Z);
+ text.ResizeAlign = EHAlignment.Center;
+
+ _Texts.Add(text);
+
+ //Create text for Title
+ textRect = new SRectF(MaxRect.X + 2 * (_TileW + _SpaceW), Rect.Y + i * (_TileH + _SpaceH), _ListTextWidth, _TileH, Rect.Z);
+ text = new CText(textRect.X, textRect.Y + (textRect.H / 2) - _SpaceH/2, textRect.Z,
+ textRect.H / 2, textRect.W, EAlignment.Left, EStyle.Normal,
+ "Normal", _Artist.Color, "");
+ text.MaxRect = new SRectF(text.MaxRect.X, text.MaxRect.Y, MaxRect.W + MaxRect.X - text.Rect.X - 5f, text.MaxRect.H, text.MaxRect.Z);
+ text.ResizeAlign = EHAlignment.Center;
+
+ _Texts.Add(text);
+ }
+
+ _ScrollRect = CBase.Settings.GetRenderRect();
+ }
+
+ private void _InitRecords()
+ {
+ SRectF rect = _Theme.SongMenuListRecord.TileRectRecord;
+ _Records = new List();
+
+ for (int i = 0; i < 5; i++)
+ {
+
+ //Create text for Record
+ var textRect = new SRectF(rect.X, rect.Y + i * (rect.H / 5 - _SpaceH), rect.W - _SpaceW, rect.H / 5 - _SpaceH, rect.Z);
+ CText text = new CText(textRect.X, textRect.Y, textRect.Z,
+ textRect.H, textRect.W, EAlignment.Left, EStyle.Normal,
+ "Normal", _Artist.Color, "");
+ text.MaxRect = new SRectF(text.MaxRect.X, text.MaxRect.Y, text.MaxRect.W + text.MaxRect.X - text.Rect.X - 5f, text.MaxRect.H, text.MaxRect.Z);
+ text.ResizeAlign = EHAlignment.Center;
+
+ _Records.Add(text);
+ }
+ }
+
+ private void _UpdateTileSelection()
+ {
+ foreach (CStatic tile in _Tiles)
+ tile.Selected = false;
+
+ int tileNr = _SelectionNr - _Offset;
+ if (tileNr >= 0 && tileNr < _Tiles.Count)
+ _Tiles[tileNr].Selected = true;
+ }
+
+ public override void Update(SScreenSongOptions songOptions)
+ {
+ if (songOptions.Selection.RandomOnly)
+ _PreviewNr = _SelectionNr;
+
+ if (_Length < 0 && CBase.Songs.IsInCategory() && CBase.BackgroundMusic.GetLength() > 0)
+ _UpdateLength(CBase.Songs.GetVisibleSong(_PreviewNr));
+ }
+
+ private void _UpdatePreview()
+ {
+ //First hide everything so we just have to set what we actually want
+ _CoverBig.Texture = _CoverBigBGTexture;
+ _Artist.Text = String.Empty;
+ _Title.Text = String.Empty;
+ _SongLength.Text = String.Empty;
+ _DuetIcon.Visible = false;
+ _VideoIcon.Visible = false;
+ _MedleyCalcIcon.Visible = false;
+ _MedleyTagIcon.Visible = false;
+ _Length = -1f;
+
+ //Check if nothing is selected (for preview)
+ if (_PreviewNr < 0)
+ return;
+
+ if (CBase.Songs.IsInCategory())
+ {
+ CSong song = CBase.Songs.GetVisibleSong(_PreviewNr);
+ //Check if we have a valid song (song still visible, index >=0 etc is checked by framework)
+ if (song == null)
+ {
+ //Display at least the category
+ CCategory category = CBase.Songs.GetCategory(CBase.Songs.GetCurrentCategoryIndex());
+ //Check if we have a valid category
+ if (category == null)
+ return;
+ _CoverBig.Texture = category.CoverTextureBig;
+ _Artist.Text = category.Name;
+ return;
+ }
+ _CoverBig.Texture = song.CoverTextureBig;
+ _Artist.Text = song.Artist;
+ _Title.Text = song.Title;
+ _DuetIcon.Visible = song.IsDuet;
+ _VideoIcon.Visible = song.VideoFileName != "";
+ _MedleyCalcIcon.Visible = song.Medley.Source == EDataSource.Calculated;
+ _MedleyTagIcon.Visible = song.Medley.Source == EDataSource.Tag;
+
+ _UpdateLength(song);
+ _UpdateRecords(song);
+ }
+ else
+ {
+ CCategory category = CBase.Songs.GetCategory(_PreviewNr);
+ //Check if we have a valid category
+ if (category == null)
+ return;
+ _CoverBig.Texture = category.CoverTextureBig;
+ _Artist.Text = category.Name;
+
+ int num = category.GetNumSongsNotSung();
+ String songOrSongs = (num == 1) ? "TR_SCREENSONG_NUMSONG" : "TR_SCREENSONG_NUMSONGS";
+ _Title.Text = CBase.Language.Translate(songOrSongs).Replace("%v", num.ToString());
+ }
+ }
+
+ private void _UpdateLength(CSong song)
+ {
+ if (song == null)
+ return;
+ float time = CBase.BackgroundMusic.GetLength();
+ if (Math.Abs(song.Finish) > 0.001)
+ time = song.Finish;
+
+ // The audiobackend is ready to return the length
+ if (time > 0)
+ {
+ time -= song.Start;
+ var min = (int)Math.Floor(time / 60f);
+ var sec = (int)(time - min * 60f);
+ _SongLength.Text = min.ToString("00") + ":" + sec.ToString("00");
+ _Length = time;
+ }
+ else
+ _SongLength.Text = "...";
+ }
+
+ private void _UpdateRecords(CSong song)
+ {
+ if (song == null)
+ return;
+
+ List _Scores = CBase.DataBase.LoadScore(song.ID,EGameMode.TR_GAMEMODE_NORMAL, EHighscoreStyle.TR_CONFIG_HIGHSCORE_LIST_ALL);
+
+ for (int i = 0; i < 5; i++)
+ {
+ if (i < _Scores.Count)
+ {
+ SDBScoreEntry score = _Scores[i];
+ _Records[i].Text = (i+1) +". "+ score.Name + " " + score.Score + " ("+ CBase.Language.Translate(score.Difficulty.ToString()) + ") " + score.Date;
+ }else
+ {
+ _Records[i].Text = "";
+ }
+ }
+ }
+
+ public override void OnShow()
+ {
+ _LastKnownElements = -1; //Force refresh of list
+ if (!CBase.Songs.IsInCategory())
+ {
+ if ((CBase.Songs.GetTabs() == EOffOn.TR_CONFIG_OFF && CBase.Songs.GetNumCategories() > 0) || CBase.Songs.GetNumCategories() == 1)
+ _EnterCategory(0);
+ }
+ if (CBase.Songs.IsInCategory())
+ SetSelectedSong(_SelectionNr < 0 ? 0 : _SelectionNr);
+ else
+ SetSelectedCategory(_SelectionNr < 0 ? 0 : _SelectionNr);
+ _PreviewNr = _SelectionNr;
+ _UpdateListIfRequired();
+ }
+
+ public override bool HandleInput(ref SKeyEvent keyEvent, SScreenSongOptions options)
+ {
+ if (keyEvent.KeyPressed)
+ return false;
+
+ bool moveAllowed = !options.Selection.RandomOnly || (options.Selection.CategoryChangeAllowed && !CBase.Songs.IsInCategory());
+ bool catChangePossible = CBase.Songs.GetTabs() == EOffOn.TR_CONFIG_ON && options.Selection.CategoryChangeAllowed;
+
+ //If nothing selected set a reasonable default value
+ if (keyEvent.IsArrowKey() && moveAllowed && _SelectionNr < 0)
+ _SelectionNr = (_PreviewNr < 0) ? _Offset : _PreviewNr;
+
+ switch (keyEvent.Key)
+ {
+ case Keys.Enter:
+ if (CBase.Songs.IsInCategory())
+ {
+ if (_SelectionNr >= 0 && _PreviewNr != _SelectionNr)
+ {
+ _PreviewNr = _SelectionNr;
+ keyEvent.Handled = true;
+ }
+ }
+ else
+ {
+ _EnterCategory(_PreviewNr);
+ keyEvent.Handled = true;
+ }
+ break;
+
+ case Keys.Escape:
+ case Keys.Back:
+ if (CBase.Songs.IsInCategory() && catChangePossible)
+ {
+ _LeaveCategory();
+ keyEvent.Handled = true;
+ }
+ break;
+
+ case Keys.PageUp:
+ if (catChangePossible)
+ {
+ _PrevCategory();
+ keyEvent.Handled = true;
+ }
+ break;
+
+ case Keys.PageDown:
+ if (catChangePossible)
+ {
+ _NextCategory();
+ keyEvent.Handled = true;
+ }
+ break;
+
+ case Keys.Left:
+ //Check for >0 so we do not allow selection of nothing (-1)
+ if (_SelectionNr > 0 && moveAllowed)
+ {
+ _SelectionNr--;
+ keyEvent.Handled = true;
+ }
+ break;
+
+ case Keys.Right:
+ if (moveAllowed)
+ {
+ _SelectionNr++;
+ keyEvent.Handled = true;
+ }
+ break;
+
+ case Keys.Up:
+ if (keyEvent.ModShift)
+ {
+ if (catChangePossible)
+ {
+ _PrevCategory();
+ keyEvent.Handled = true;
+ }
+ }
+ else if (_SelectionNr >= 1 && moveAllowed)
+ {
+ _SelectionNr -= 1;
+ keyEvent.Handled = true;
+ }
+ break;
+
+ case Keys.Down:
+ if (keyEvent.ModShift)
+ {
+ if (catChangePossible)
+ {
+ _NextCategory();
+ keyEvent.Handled = true;
+ }
+ }
+ else if (moveAllowed)
+ {
+ _SelectionNr += 1;
+ keyEvent.Handled = true;
+ }
+ break;
+ }
+ if (!CBase.Songs.IsInCategory())
+ _PreviewNr = _SelectionNr;
+ return keyEvent.Handled;
+ }
+
+ public override bool HandleMouse(ref SMouseEvent mouseEvent, SScreenSongOptions songOptions)
+ {
+ if (!songOptions.Selection.RandomOnly || (!CBase.Songs.IsInCategory() && songOptions.Selection.CategoryChangeAllowed))
+ {
+ if (mouseEvent.Wheel != 0 && CHelper.IsInBounds(_ScrollRect, mouseEvent))
+ _UpdateList(_Offset + mouseEvent.Wheel);
+
+ int lastSelection = _SelectionNr;
+ int i = 0;
+ bool somethingSelected = false;
+
+ foreach (CStatic tile in _Tiles)
+ {
+ //create a rect including the cover and text of the song.
+ //(this way mouse over text should make a selection as well)
+ SRectF songRect = new SRectF(tile.Rect.X, tile.Rect.Y, Rect.W, tile.Rect.H, tile.Rect.Z);
+ if (tile.Texture != _CoverBGTexture && CHelper.IsInBounds(songRect, mouseEvent) && tile.Color.A != 0)
+ {
+ somethingSelected = true;
+ _SelectionNr = i + _Offset;
+ if (!CBase.Songs.IsInCategory())
+ _PreviewNr = i + _Offset;
+ break;
+ }
+ i++;
+ }
+ //Reset selection only if we moved out of the rect to avoid loosing it when selecting random songs
+ if (_MouseWasInRect && !somethingSelected)
+ _SelectionNr = -1;
+ if (mouseEvent.Sender == ESender.WiiMote && _SelectionNr != lastSelection && _SelectionNr != -1)
+ CBase.Controller.SetRumble(0.050f);
+ }
+ _MouseWasInRect = CHelper.IsInBounds(Rect, mouseEvent);
+
+ if (mouseEvent.RB)
+ {
+ if (CBase.Songs.IsInCategory() && CBase.Songs.GetNumCategories() > 0 && CBase.Songs.GetTabs() == EOffOn.TR_CONFIG_ON &&
+ songOptions.Selection.CategoryChangeAllowed)
+ {
+ _LeaveCategory();
+ return true;
+ }
+ if (CBase.Songs.GetTabs() == EOffOn.TR_CONFIG_OFF && !songOptions.Selection.PartyMode)
+ {
+ CBase.Graphics.FadeTo(EScreen.Main);
+ return true;
+ }
+ }
+ else if (mouseEvent.LB)
+ {
+ if (_SelectionNr >= 0 && _MouseWasInRect)
+ {
+ if (CBase.Songs.IsInCategory())
+ {
+ if (_PreviewNr == _SelectionNr)
+ return false;
+ _PreviewNr = _SelectionNr;
+ }
+ else
+ EnterSelectedCategory();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public override void Draw()
+ {
+ foreach (CStatic tile in _Tiles)
+ {
+ if (tile.Selected)
+ tile.Draw(EAspect.Crop, SelectedTileZoomFactor, -0.1f);
+ else
+ {
+ EAspect aspect = (tile.Texture != _CoverBGTexture) ? EAspect.Crop : EAspect.Stretch;
+ tile.Draw(aspect);
+ }
+ }
+
+ //highlight the text of the selected song
+ //int i = 0;
+ //foreach (CText text in _Texts)
+ //{
+ // if (i < _Tiles.Count && _Tiles[i].Selected)
+ // text.Font.Style = EStyle.BoldItalic;
+ // else if (i < _Tiles.Count)
+ // text.Font.Style = EStyle.Normal;
+ // else
+ // text.Text = "";
+ // text.Draw();
+ // i++;
+ //}
+
+ for (int k = 0; k < _Tiles.Count; k++)
+ {
+ CText artist = _Texts[k * 2];
+ CText title = _Texts[k * 2 + 1];
+
+ if (_Tiles[k].Selected)
+ {
+ artist.Font.Style = EStyle.BoldItalic;
+ title.Font.Style = EStyle.BoldItalic;
+ }
+ else
+ {
+ artist.Font.Style = EStyle.Normal;
+ title.Font.Style = EStyle.Normal;
+ }
+
+ artist.Draw();
+ title.Draw();
+ }
+
+ foreach (CText record in _Records)
+ {
+ record.Draw();
+ }
+
+ _TextBG.Draw();
+
+ CTextureRef vidtex = CBase.BackgroundMusic.IsPlayingPreview() ? CBase.BackgroundMusic.GetVideoTexture() : null;
+
+ if (vidtex != null)
+ {
+ if (vidtex.Color.A < 1)
+ _CoverBig.Draw(EAspect.LetterBox);
+ SRectF rect = CHelper.FitInBounds(_CoverBig.Rect, vidtex.OrigAspect, EAspect.LetterBox);
+ CBase.Drawing.DrawTexture(vidtex, rect, vidtex.Color, _CoverBig.Rect);
+ CBase.Drawing.DrawTextureReflection(vidtex, rect, vidtex.Color, _CoverBig.Rect, _CoverBig.ReflectionSpace, _CoverBig.ReflectionHeight);
+ }
+ else
+ _CoverBig.Draw(EAspect.LetterBox);
+
+ foreach (IMenuElement element in _SubElements)
+ element.Draw();
+ }
+
+ public override CStatic GetSelectedSongCover()
+ {
+ return _Tiles.FirstOrDefault(tile => tile.Selected);
+ }
+
+ public override bool IsMouseOverSelectedSong(SMouseEvent mEvent)
+ {
+ for (int i = 0; i < _Tiles.Count; i++)
+ {
+ if (!_Tiles[i].Selected)
+ continue;
+ return CHelper.IsInBounds(_Tiles[i].Rect, mEvent)
+ || CHelper.IsInBounds(_Texts[i * 2].Rect, mEvent)
+ || CHelper.IsInBounds(_Texts[i * 2 + 1].Rect, mEvent);
+ }
+ return false;
+ }
+
+ protected override void _EnterCategory(int categoryNr)
+ {
+ base._EnterCategory(categoryNr);
+
+ SetSelectedSong(0);
+ _UpdateListIfRequired();
+ }
+
+ protected override void _LeaveCategory()
+ {
+ base._LeaveCategory();
+
+ SetSelectedCategory(0);
+ _UpdateListIfRequired();
+ }
+
+ private void _NextCategory()
+ {
+ if (CBase.Songs.IsInCategory())
+ {
+ CBase.Songs.NextCategory();
+ _EnterCategory(CBase.Songs.GetCurrentCategoryIndex());
+ }
+ }
+
+ private void _PrevCategory()
+ {
+ if (CBase.Songs.IsInCategory())
+ {
+ CBase.Songs.PrevCategory();
+ _EnterCategory(CBase.Songs.GetCurrentCategoryIndex());
+ }
+ }
+
+ private void _UpdateListIfRequired()
+ {
+ int curElements = CBase.Songs.IsInCategory() ? CBase.Songs.GetNumSongsVisible() : CBase.Songs.GetNumCategories();
+ if ((_LastKnownElements == curElements) && (_LastKnownCategory == CBase.Songs.GetCurrentCategoryIndex()))
+ return;
+
+ _LastKnownCategory = CBase.Songs.GetCurrentCategoryIndex();
+ _LastKnownElements = curElements;
+ CBase.Songs.UpdateRandomSongList();
+ _UpdateList(true);
+ }
+
+ private void _UpdateList(bool force = false)
+ {
+ int offset;
+ if (_SelectionNr < _Offset && _SelectionNr >= 0)
+ offset = _SelectionNr;
+ else if (_SelectionNr >= _Offset + _ListLength)
+ offset = _SelectionNr - _ListLength + 1;
+ else
+ offset = _Offset;
+ _UpdateList(offset, force);
+ }
+
+ private void _UpdateList(int offset, bool force = false)
+ {
+ bool isInCategory = CBase.Songs.IsInCategory();
+ int itemCount = isInCategory ? CBase.Songs.GetNumSongsVisible() : CBase.Songs.GetNumCategories();
+ int totalSongNumber = CBase.Songs.GetNumSongs();
+
+ offset = offset.Clamp(0, itemCount - _ListLength, true);
+
+ if (offset == _Offset && !force)
+ return;
+
+ for (int i = 0; i < _Tiles.Count; i++)
+ {
+ if (i + offset < itemCount)
+ {
+ _Tiles[i].Color = new SColorF(1f, 1f, 1f, 1f);
+ if (isInCategory)
+ {
+ CSong currentSong = CBase.Songs.GetVisibleSong(i + offset);
+ _Tiles[i].Texture = currentSong.CoverTextureSmall;
+ _Texts[i * 2].Text = currentSong.Artist;
+ _Texts[i * 2 + 1].Text = currentSong.Title;
+ }
+ else
+ {
+ CCategory currentCat = CBase.Songs.GetCategory(i + offset);
+ _Tiles[i].Texture = currentCat.CoverTextureSmall;
+ int num = currentCat.GetNumSongsNotSung();
+ String songOrSongs = (num == 1) ? "TR_SCREENSONG_NUMSONG" : "TR_SCREENSONG_NUMSONGS";
+ _Texts[i * 2].Text = currentCat.Name + " " + CBase.Language.Translate(songOrSongs).Replace("%v", num.ToString());
+ }
+ }
+ else
+ {
+ _Tiles[i].Color.A = 0;
+ _Texts[i].Text = "";
+ }
+ }
+ _Offset = offset;
+ }
+
+ public override void LoadSkin()
+ {
+ foreach (IThemeable themeable in _SubElements.OfType())
+ themeable.LoadSkin();
+ // Those are drawn seperately so they are not in the above list
+ _CoverBig.LoadSkin();
+ _TextBG.LoadSkin();
+
+ base.LoadSkin();
+ }
+ }
+}
\ No newline at end of file
diff --git a/VocaluxeLib/VocaluxeLib.csproj b/VocaluxeLib/VocaluxeLib.csproj
index 5222c389..e5d9d606 100644
--- a/VocaluxeLib/VocaluxeLib.csproj
+++ b/VocaluxeLib/VocaluxeLib.csproj
@@ -110,6 +110,7 @@
+
@@ -150,6 +151,9 @@
+
+
+