Add new Sorting Capabilities for Profile list
This commit is contained in:
@@ -2699,6 +2699,11 @@
|
||||
<EnumValue name=''ProfileSlot_Player2'' value='1'/>
|
||||
<EnumValue name=''ProfileSlot_Machine'' value='2'/>
|
||||
</Enum>
|
||||
<Enum name='ProfileSortOrder'>
|
||||
<EnumValue name=''ProfileSortOrder_Priority'' value='0'/>
|
||||
<EnumValue name=''ProfileSortOrder_Recent'' value='1'/>
|
||||
<EnumValue name=''ProfileSortOrder_Alphabetical'' value='2'/>
|
||||
</Enum>
|
||||
<Enum name='ProfileType'>
|
||||
<EnumValue name=''ProfileType_Guest'' value='0'/>
|
||||
<EnumValue name=''ProfileType_Normal'' value='1'/>
|
||||
|
||||
@@ -4747,7 +4747,8 @@ prev_note_name, succeeded = options:NoteSkin("cel")
|
||||
Returns the number of trails with the specified StepsType and Difficulty that you've scored a certain Grade <code>g</code> on.
|
||||
</Function>
|
||||
<Function name='GetType' return='ProfileType' arguments=''>
|
||||
Returns the type of the profile. The type of the profile is only used to determine where the profile shows up in the list of profiles, and that problem is already handled by ProfileManager, so if you're reading this, this function only exists so you can make your theme color this profile's list entry based on the type or something like that.
|
||||
Returns the type of the profile. The StepMania engine uses ProfileType to sort the list of profiles, with <code>Guest</code> profiles appearing first, then <code>Normal</code>, then <code>Test</code>.<br />
|
||||
Additional subsorting can be configured with <Link class='ENUM' function='ProfileSortOrder' />.
|
||||
</Function>
|
||||
<Function name='GetUserTable' return='table' arguments=''>
|
||||
Returns the user table for this Profile.
|
||||
@@ -6858,6 +6859,13 @@ end
|
||||
Horizontal alignment. See <Link class='Actor' function='horizalign' />.
|
||||
</Description>
|
||||
</Enum>
|
||||
<Enum name='ProfileSortOrder'>
|
||||
<Description>
|
||||
Possible values for the <code>ProfileSortOrder</code> preference. The engine initially sorts profiles based on their <Link class='ENUM' function='ProfileType' />, showing <code>Guest</code> profiles first, then <code>Normal</code>, then <code>Test</code>. <code>ProfileSortOrder</code> allows additional subsorts to be configured.<br />
|
||||
<code>Priority</code> allows users to manually sort profiles using the <code>Priority=</code> key in each profile's Type.ini file. New profiles are created with <code>Priority=0</code>. A profile with <code>Priority=0</code> will appear before any profiles with <code>Priority=1</code> which will appear before any profiles with <code>Priority=2</code> and so on.<br />
|
||||
<code>Recent</code> automatically sorts profiles in the order they are used, with the most recently used profile appearing first.
|
||||
</Description>
|
||||
</Enum>
|
||||
<Enum name='VertAlign'>
|
||||
<Description>
|
||||
Vertical alignment. See <Link class='Actor' function='vertalign' />.
|
||||
|
||||
@@ -691,6 +691,7 @@ x2.5=2.5x
|
||||
1000000=1000000
|
||||
Actual=Actual
|
||||
Add=Additive
|
||||
Alphabetical=Alphabetical
|
||||
All Music=All Music
|
||||
AllDifficulties=All Difficulties
|
||||
AllGroups=All Groups
|
||||
@@ -839,6 +840,7 @@ On (recommended)=On (recommended)
|
||||
Only Dedicated Buttons=Only Dedicated Buttons
|
||||
Overhead=Overhead
|
||||
Pay=Pay
|
||||
Priority=Priority
|
||||
Percent=Percent
|
||||
Planted=Planted
|
||||
Press Start=Press Start
|
||||
@@ -851,6 +853,7 @@ Random Movies=Random Movies
|
||||
Ranking=Ranking
|
||||
Ranking Songs=Ranking Songs
|
||||
Really Fast=Really Fast
|
||||
Recent=Recently Used
|
||||
RegularCourses=Regular
|
||||
Remove=Remove
|
||||
RemoveCombinations=Remove
|
||||
|
||||
@@ -3096,7 +3096,7 @@ Line21="conf,RateModPreservesPitch"
|
||||
Fallback="ScreenOptionsServiceChild"
|
||||
NextScreen="ScreenOptionsService"
|
||||
PrevScreen="ScreenOptionsService"
|
||||
LineNames="3,4,8,SI,SM,HN,11,13,14,15,16,28,29,30,31,32,ECPT"
|
||||
LineNames="3,4,8,SI,SM,HN,11,13,14,15,16,28,29,30,31,32,33,ECPT"
|
||||
#LineScore="lua,UserPrefScoringMode()"
|
||||
Line3="conf,TimingWindowScale"
|
||||
Line4="conf,LifeDifficulty"
|
||||
@@ -3113,6 +3113,8 @@ Line28="conf,AutogenSteps"
|
||||
Line29="conf,AutogenGroupCourses"
|
||||
Line30="conf,FastLoad"
|
||||
Line32="conf,AllowSongDeletion"
|
||||
Line33="conf,ProfileSortOrder"
|
||||
Line33="conf,ProfileSortOrderAscending"
|
||||
LineECPT="conf,EditClearPromptThreshold"
|
||||
|
||||
# unused options
|
||||
|
||||
@@ -834,6 +834,20 @@ void GameState::FinishStage()
|
||||
{
|
||||
Profile* pProfile = PROFILEMAN->GetProfile(p);
|
||||
pProfile->m_iCurrentCombo = STATSMAN->m_CurStageStats.m_player[p].m_iCurCombo;
|
||||
//If the sort order is Recent, move the profile to the top of the list.
|
||||
if (PREFSMAN->m_ProfileSortOrder == ProfileSortOrder_Recent && PROFILEMAN->IsPersistentProfile(p))
|
||||
{
|
||||
int numLocalProfiles = PROFILEMAN->GetNumLocalProfiles();
|
||||
for (int i = 0; i < numLocalProfiles; i++)
|
||||
{
|
||||
Profile *profile = PROFILEMAN->GetLocalProfileFromIndex(i);
|
||||
if (profile->m_sGuid == pProfile->m_sGuid)
|
||||
{
|
||||
PROFILEMAN->MoveProfileTopBottom(i, PREFSMAN->m_bProfileSortOrderAscending);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( m_bDemonstrationOrJukebox )
|
||||
|
||||
@@ -125,6 +125,15 @@ XToString( BackgroundFitMode );
|
||||
StringToX( BackgroundFitMode );
|
||||
LuaXType( BackgroundFitMode );
|
||||
|
||||
static const char* ProfileSortOrderNames[] = {
|
||||
"Priority",
|
||||
"Recent",
|
||||
"Alphabetical"
|
||||
};
|
||||
XToString(ProfileSortOrder);
|
||||
StringToX(ProfileSortOrder);
|
||||
LuaXType(ProfileSortOrder);
|
||||
|
||||
bool g_bAutoRestart = false;
|
||||
#ifdef DEBUG
|
||||
# define TRUE_IF_DEBUG true
|
||||
@@ -258,6 +267,8 @@ PrefsManager::PrefsManager() :
|
||||
m_bAnisotropicFiltering ( "AnisotropicFiltering", false ),
|
||||
|
||||
m_bSignProfileData ( "SignProfileData", false ),
|
||||
m_ProfileSortOrder ( "ProfileSortOrder", ProfileSortOrder_Priority ),
|
||||
m_bProfileSortOrderAscending ( "ProfileSortOrderAscending", true ),
|
||||
m_CourseSortOrder ( "CourseSortOrder", COURSE_SORT_SONGS ),
|
||||
m_bSubSortByNumSteps ( "SubSortByNumSteps", false ),
|
||||
m_GetRankingName ( "GetRankingName", RANKING_ON ),
|
||||
|
||||
@@ -112,6 +112,18 @@ enum BackgroundFitMode
|
||||
BackgroundFitMode_Invalid
|
||||
};
|
||||
|
||||
// Profile sort orders exist for sorting the list of profiles.
|
||||
// Regardless of sort order, Guest profiles are always at the top of the list
|
||||
// and Test profiles are always at the bottom of the list.
|
||||
enum ProfileSortOrder
|
||||
{
|
||||
ProfileSortOrder_Priority, // Sort based on the Priority defined in a profile's Type.ini
|
||||
ProfileSortOrder_Recent, // Sorts profiles by most recently used.
|
||||
ProfileSortOrder_Alphabetical, // Sorts profiles alphabetically.
|
||||
NUM_ProfileSortOrder,
|
||||
ProfileSortOrder_Invalid
|
||||
};
|
||||
|
||||
/** @brief Holds user-chosen preferences that are saved between sessions. */
|
||||
class PrefsManager
|
||||
{
|
||||
@@ -271,6 +283,13 @@ public:
|
||||
// profile's data will be discarded.
|
||||
Preference<bool> m_bSignProfileData;
|
||||
|
||||
// Used to control the ordering of the player profiles.
|
||||
// See the the definition of ProfileSortOrder above about the available sort options.
|
||||
Preference<ProfileSortOrder> m_ProfileSortOrder;
|
||||
|
||||
// Determines whether the ProfileSortOrder is in ascending order (true) or descending order (false).
|
||||
Preference<bool> m_bProfileSortOrderAscending;
|
||||
|
||||
// course ranking
|
||||
Preference<CourseSortOrders> m_CourseSortOrder;
|
||||
Preference<bool> m_bSubSortByNumSteps;
|
||||
|
||||
@@ -1331,6 +1331,11 @@ void Profile::LoadTypeFromDir(RString dir)
|
||||
}
|
||||
}
|
||||
data->GetAttrValue("Priority", m_ListPriority);
|
||||
RString date_str;
|
||||
if (data->GetAttrValue("LastPlayedDate", date_str))
|
||||
{
|
||||
m_LastPlayedDate.FromString(date_str);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1501,6 +1506,7 @@ void Profile::SaveTypeToDir(RString dir) const
|
||||
IniFile ini;
|
||||
ini.SetValue("ListPosition", "Type", ProfileTypeToString(m_Type));
|
||||
ini.SetValue("ListPosition", "Priority", m_ListPriority);
|
||||
ini.SetValue("ListPosition", "LastPlayedDate", DateTime::GetNowDateTime().GetString());
|
||||
ini.WriteFile(dir + TYPE_INI);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -62,7 +62,7 @@ class Steps;
|
||||
class Course;
|
||||
struct Game;
|
||||
|
||||
// Profile types exist for sorting the list of profiles.
|
||||
// Profile types exist for distinguishing profiles and facilitating sorting.
|
||||
// Guest profiles at the top, test at the bottom.
|
||||
enum ProfileType
|
||||
{
|
||||
|
||||
+251
-5
@@ -439,6 +439,22 @@ void ProfileManager::RefreshLocalProfilesFromDisk()
|
||||
{
|
||||
UnloadAllLocalProfiles();
|
||||
|
||||
switch(PREFSMAN->m_ProfileSortOrder)
|
||||
{
|
||||
case ProfileSortOrder_Alphabetical:
|
||||
LoadLocalProfilesByName();
|
||||
break;
|
||||
case ProfileSortOrder_Recent:
|
||||
LoadLocalProfilesByRecent();
|
||||
break;
|
||||
default:
|
||||
LoadLocalProfilesByPriority();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ProfileManager::LoadLocalProfilesByPriority()
|
||||
{
|
||||
std::vector<RString> profile_ids;
|
||||
GetDirListing(USER_PROFILES_DIR + "*", profile_ids, true, true);
|
||||
// Profiles have 3 types:
|
||||
@@ -490,7 +506,136 @@ void ProfileManager::RefreshLocalProfilesFromDisk()
|
||||
{
|
||||
curr.profile.LoadAllFromDir(curr.sDir, PREFSMAN->m_bSignProfileData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ProfileManager::LoadLocalProfilesByName()
|
||||
{
|
||||
std::vector<RString> profile_ids;
|
||||
GetDirListing(USER_PROFILES_DIR + "*", profile_ids, true, true);
|
||||
|
||||
// Create separate vectors for each profile type
|
||||
std::vector<DirAndProfile> guestProfiles;
|
||||
std::vector<DirAndProfile> normalProfiles;
|
||||
std::vector<DirAndProfile> testProfiles;
|
||||
|
||||
for (RString const &id : profile_ids)
|
||||
{
|
||||
DirAndProfile derp;
|
||||
derp.sDir= id + "/";
|
||||
derp.profile.LoadEditableDataFromDir(derp.sDir);
|
||||
derp.profile.LoadTypeFromDir(derp.sDir);
|
||||
// insert profile into the appropriate vector based on profile type
|
||||
switch(derp.profile.m_Type)
|
||||
{
|
||||
case ProfileType_Guest:
|
||||
guestProfiles.push_back(derp);
|
||||
break;
|
||||
case ProfileType_Normal:
|
||||
normalProfiles.push_back(derp);
|
||||
break;
|
||||
case ProfileType_Test:
|
||||
testProfiles.push_back(derp);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Sort each vector by display name
|
||||
if (PREFSMAN->m_bProfileSortOrderAscending) {
|
||||
auto displayNameAscending = [](const DirAndProfile &a, const DirAndProfile &b)
|
||||
{
|
||||
return a.profile.m_sDisplayName.CompareNoCase(b.profile.m_sDisplayName) < 0;
|
||||
};
|
||||
std::sort(guestProfiles.begin(), guestProfiles.end(), displayNameAscending);
|
||||
std::sort(normalProfiles.begin(), normalProfiles.end(), displayNameAscending);
|
||||
std::sort(testProfiles.begin(), testProfiles.end(), displayNameAscending);
|
||||
} else {
|
||||
auto displayNameDescending = [](const DirAndProfile &a, const DirAndProfile &b)
|
||||
{
|
||||
return a.profile.m_sDisplayName.CompareNoCase(b.profile.m_sDisplayName) > 0;
|
||||
};
|
||||
std::sort(guestProfiles.begin(), guestProfiles.end(), displayNameDescending);
|
||||
std::sort(normalProfiles.begin(), normalProfiles.end(), displayNameDescending);
|
||||
std::sort(testProfiles.begin(), testProfiles.end(), displayNameDescending);
|
||||
}
|
||||
|
||||
add_category_to_global_list(guestProfiles);
|
||||
add_category_to_global_list(normalProfiles);
|
||||
add_category_to_global_list(testProfiles);
|
||||
|
||||
for (DirAndProfile &curr : g_vLocalProfile)
|
||||
{
|
||||
curr.profile.LoadAllFromDir(curr.sDir, PREFSMAN->m_bSignProfileData);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// This function is used within RefreshLocalProfilesFromDisk() to sort the profiles by date.
|
||||
void ProfileManager::LoadLocalProfilesByRecent()
|
||||
{
|
||||
|
||||
std::vector<RString> profile_ids;
|
||||
GetDirListing(USER_PROFILES_DIR + "*", profile_ids, true, true);
|
||||
|
||||
// Create separate vectors for each profile type
|
||||
std::vector<DirAndProfile> guestProfiles;
|
||||
std::vector<DirAndProfile> normalProfiles;
|
||||
std::vector<DirAndProfile> testProfiles;
|
||||
|
||||
// The type data for a profile is in its own file so that loading isn't
|
||||
// slowed down by copying temporary profiles around to make sure the list
|
||||
// is sorted. The profiles are loaded at the end. -Kyz
|
||||
for (RString const &id : profile_ids)
|
||||
{
|
||||
DirAndProfile derp;
|
||||
derp.sDir= id + "/";
|
||||
derp.profile.LoadTypeFromDir(derp.sDir);
|
||||
// insert profile into the appropriate vector based on profile type
|
||||
switch(derp.profile.m_Type)
|
||||
{
|
||||
case ProfileType_Guest:
|
||||
guestProfiles.push_back(derp);
|
||||
break;
|
||||
case ProfileType_Normal:
|
||||
normalProfiles.push_back(derp);
|
||||
break;
|
||||
case ProfileType_Test:
|
||||
testProfiles.push_back(derp);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Sort each vector by date
|
||||
if (PREFSMAN->m_bProfileSortOrderAscending) {
|
||||
auto lastPlayedAscending = [](const DirAndProfile &a, const DirAndProfile &b)
|
||||
{
|
||||
return a.profile.m_LastPlayedDate > b.profile.m_LastPlayedDate;
|
||||
};
|
||||
std::sort(guestProfiles.begin(), guestProfiles.end(), lastPlayedAscending);
|
||||
std::sort(normalProfiles.begin(), normalProfiles.end(), lastPlayedAscending);
|
||||
std::sort(testProfiles.begin(), testProfiles.end(), lastPlayedAscending);
|
||||
} else {
|
||||
auto lastPlayedDescending = [](const DirAndProfile &a, const DirAndProfile &b)
|
||||
{
|
||||
return a.profile.m_LastPlayedDate < b.profile.m_LastPlayedDate;
|
||||
};
|
||||
std::sort(guestProfiles.begin(), guestProfiles.end(), lastPlayedDescending);
|
||||
std::sort(normalProfiles.begin(), normalProfiles.end(), lastPlayedDescending);
|
||||
std::sort(testProfiles.begin(), testProfiles.end(), lastPlayedDescending);
|
||||
}
|
||||
|
||||
add_category_to_global_list(guestProfiles);
|
||||
add_category_to_global_list(normalProfiles);
|
||||
add_category_to_global_list(testProfiles);
|
||||
|
||||
for (DirAndProfile &curr : g_vLocalProfile)
|
||||
{
|
||||
curr.profile.LoadAllFromDir(curr.sDir, PREFSMAN->m_bSignProfileData);
|
||||
}
|
||||
}
|
||||
|
||||
const Profile *ProfileManager::GetLocalProfile( const RString &sProfileID ) const
|
||||
{
|
||||
@@ -572,15 +717,17 @@ bool ProfileManager::CreateLocalProfile( RString sName, RString &sProfileIDOut )
|
||||
|
||||
static void InsertProfileIntoList(DirAndProfile& derp)
|
||||
{
|
||||
bool inserted= false;
|
||||
derp.profile.m_ListPriority= 0;
|
||||
bool inserted = false;
|
||||
derp.profile.m_ListPriority = 0;
|
||||
int index = -1;
|
||||
for (auto curr = g_vLocalProfile.begin(); curr != g_vLocalProfile.end(); ++curr)
|
||||
{
|
||||
++index;
|
||||
if(curr->profile.m_Type > derp.profile.m_Type)
|
||||
{
|
||||
derp.profile.SaveTypeToDir(derp.sDir);
|
||||
g_vLocalProfile.insert(curr, derp);
|
||||
inserted= true;
|
||||
inserted = true;
|
||||
break;
|
||||
}
|
||||
else if(curr->profile.m_Type == derp.profile.m_Type)
|
||||
@@ -588,11 +735,26 @@ static void InsertProfileIntoList(DirAndProfile& derp)
|
||||
++derp.profile.m_ListPriority;
|
||||
}
|
||||
}
|
||||
|
||||
if(!inserted)
|
||||
{
|
||||
derp.profile.SaveTypeToDir(derp.sDir);
|
||||
g_vLocalProfile.push_back(derp);
|
||||
}
|
||||
|
||||
// The above should run regardless of profile sort in case the user decides to change
|
||||
// back to priority sorting. If we're using Recent sorting, move the new profile to
|
||||
// the top, if we're using alphabetical find where it belongs.
|
||||
switch (PREFSMAN->m_ProfileSortOrder) {
|
||||
case ProfileSortOrder_Recent:
|
||||
PROFILEMAN->MoveProfileTopBottom(index, PREFSMAN->m_bProfileSortOrderAscending);
|
||||
break;
|
||||
case ProfileSortOrder_Alphabetical:
|
||||
PROFILEMAN->MoveProfileSorted(index, PREFSMAN->m_bProfileSortOrderAscending);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ProfileManager::AddLocalProfileByID( Profile *pProfile, RString sProfileID )
|
||||
@@ -648,7 +810,7 @@ bool ProfileManager::DeleteLocalProfile( RString sProfileID )
|
||||
else
|
||||
{
|
||||
LOG->Warn("[ProfileManager::DeleteLocalProfile] DeleteRecursive(%s) failed",
|
||||
sProfileID.c_str() );
|
||||
sProfileID.c_str() );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -787,6 +949,90 @@ void ProfileManager::ChangeProfileType(int index, ProfileType new_type)
|
||||
InsertProfileIntoList(derp);
|
||||
}
|
||||
|
||||
void ProfileManager::MoveProfileTopBottom(int index, bool top)
|
||||
{
|
||||
if (index < 0 || static_cast<size_t>(index) >= g_vLocalProfile.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int swindex = 0;
|
||||
// There may be guest profiles at the top of the list, so we need to skip over them if moving to the top.
|
||||
// If we're moving the profile to the bottom we should stop once we find the first test profile.
|
||||
for (size_t i= 0; i < g_vLocalProfile.size(); ++i)
|
||||
{
|
||||
ProfileType type= g_vLocalProfile[i].profile.m_Type;
|
||||
if (!top)
|
||||
{
|
||||
if (type == ProfileType_Test)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (type != ProfileType_Guest)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
swindex++;
|
||||
}
|
||||
if ((top && index < swindex) || (!top && index > swindex))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Save the profile to move
|
||||
DirAndProfile profile = g_vLocalProfile[index];
|
||||
// Remove the profile from its current position
|
||||
g_vLocalProfile.erase(g_vLocalProfile.begin() + index);
|
||||
// Insert the profile at the beginning of the list
|
||||
g_vLocalProfile.insert(g_vLocalProfile.begin() + swindex, profile);
|
||||
}
|
||||
|
||||
void ProfileManager::MoveProfileSorted(int index, bool bAscending) {
|
||||
|
||||
if (index < 0 || static_cast<size_t>(index) >= g_vLocalProfile.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int swindex = 0;
|
||||
// There may be guest profiles at the top of the list, so we need to skip over them.
|
||||
for (size_t i= 0; i < g_vLocalProfile.size(); ++i)
|
||||
{
|
||||
ProfileType type= g_vLocalProfile[i].profile.m_Type;
|
||||
if (type != ProfileType_Guest)
|
||||
{
|
||||
break;
|
||||
}
|
||||
swindex++;
|
||||
}
|
||||
|
||||
if (index < swindex)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Copy the profile to be moved
|
||||
DirAndProfile temp = g_vLocalProfile[index];
|
||||
|
||||
// Remove the profile from the list
|
||||
g_vLocalProfile.erase(g_vLocalProfile.begin()+index);
|
||||
|
||||
// Find the correct location to insert the profile
|
||||
auto it = std::lower_bound(g_vLocalProfile.begin()+swindex, g_vLocalProfile.end(), temp,
|
||||
[bAscending](const DirAndProfile &a, const DirAndProfile &b)
|
||||
{
|
||||
if (bAscending)
|
||||
return a.profile.m_sDisplayName < b.profile.m_sDisplayName;
|
||||
else
|
||||
return a.profile.m_sDisplayName > b.profile.m_sDisplayName;
|
||||
});
|
||||
g_vLocalProfile.insert(it, temp);
|
||||
}
|
||||
|
||||
void ProfileManager::MoveProfilePriority(int index, bool up)
|
||||
{
|
||||
if(index < 0 || static_cast<size_t>(index) >= g_vLocalProfile.size())
|
||||
|
||||
@@ -15,6 +15,7 @@ class Course;
|
||||
class Trail;
|
||||
struct HighScore;
|
||||
struct lua_State;
|
||||
|
||||
/** @brief Interface to machine and memory card profiles. */
|
||||
class ProfileManager
|
||||
{
|
||||
@@ -29,6 +30,10 @@ public:
|
||||
// local profiles
|
||||
void UnloadAllLocalProfiles();
|
||||
void RefreshLocalProfilesFromDisk();
|
||||
void LoadLocalProfilesByPriority();
|
||||
void LoadLocalProfilesByRecent();
|
||||
void LoadLocalProfilesByName();
|
||||
|
||||
const Profile *GetLocalProfile( const RString &sProfileID ) const;
|
||||
Profile *GetLocalProfile( const RString &sProfileID ) { return (Profile*) ((const ProfileManager *) this)->GetLocalProfile(sProfileID); }
|
||||
Profile *GetLocalProfileFromIndex( int iIndex );
|
||||
@@ -58,6 +63,8 @@ public:
|
||||
void MergeLocalProfileIntoMachine(RString const& from_id, bool skip_totals);
|
||||
void ChangeProfileType(int index, ProfileType new_type);
|
||||
void MoveProfilePriority(int index, bool up);
|
||||
void MoveProfileTopBottom(int index, bool top);
|
||||
void MoveProfileSorted(int index, bool bAscending);
|
||||
|
||||
// General data
|
||||
void IncrementToastiesCount( PlayerNumber pn );
|
||||
|
||||
@@ -244,7 +244,12 @@ void ScreenOptionsManageProfiles::HandleScreenMessage( const ScreenMessage SM )
|
||||
|
||||
RString sNewName = ScreenTextEntry::s_sLastAnswer;
|
||||
PROFILEMAN->RenameLocalProfile( GAMESTATE->m_sEditLocalProfileID, sNewName );
|
||||
|
||||
if (PREFSMAN->m_ProfileSortOrder == ProfileSortOrder_Alphabetical)
|
||||
{
|
||||
PROFILEMAN->MoveProfileSorted(
|
||||
GetLocalProfileIndexWithFocus(),
|
||||
PREFSMAN->m_bProfileSortOrderAscending);
|
||||
}
|
||||
SCREENMAN->SetNewScreen( this->m_sName ); // reload
|
||||
}
|
||||
}
|
||||
@@ -449,8 +454,14 @@ void ScreenOptionsManageProfiles::ProcessMenuStart( const InputEventPlus & )
|
||||
ADD_ACTION( ProfileAction_ChangeToGuest );
|
||||
ADD_ACTION( ProfileAction_ChangeToNormal );
|
||||
ADD_ACTION( ProfileAction_ChangeToTest );
|
||||
ADD_ACTION( ProfileAction_MoveUp );
|
||||
ADD_ACTION( ProfileAction_MoveDown );
|
||||
// There technically isn't an issue keeping these enabled for other ProfileSorts,
|
||||
// but it's not really useful as it would be overwritten.
|
||||
if (PREFSMAN->m_ProfileSortOrder == ProfileSortOrder_Priority)
|
||||
{
|
||||
ADD_ACTION( ProfileAction_MoveUp );
|
||||
ADD_ACTION( ProfileAction_MoveDown );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int iWidth, iX, iY;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "GameState.h"
|
||||
#include "ScreenManager.h"
|
||||
#include "SongManager.h"
|
||||
#include "ProfileManager.h"
|
||||
#include "PrefsManager.h"
|
||||
#include "StepMania.h"
|
||||
#include "RageSoundManager.h"
|
||||
@@ -111,6 +112,12 @@ void ScreenOptionsMaster::HandleScreenMessage( const ScreenMessage SM )
|
||||
for( unsigned r=0; r<m_pRows.size(); r++ ) // foreach row
|
||||
ExportOptions( r, vpns );
|
||||
|
||||
if (m_iChangeMask & OPT_APPLY_PROFILES)
|
||||
{
|
||||
// If we're changing profile settings such as sort order, we need to reload them
|
||||
PROFILEMAN->RefreshLocalProfilesFromDisk();
|
||||
}
|
||||
|
||||
if( m_iChangeMask & OPT_APPLY_ASPECT_RATIO )
|
||||
{
|
||||
THEME->UpdateLuaGlobals(); // This needs to be done before resetting the projection matrix below
|
||||
|
||||
@@ -885,7 +885,11 @@ static void InitializeConfOptions()
|
||||
ADD( ConfOption( "MaxHighScoresPerListForMachine", MaxHighScoresPerListForMachine, "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20") );
|
||||
ADD( ConfOption( "MaxHighScoresPerListForPlayer", MaxHighScoresPerListForPlayer, "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20") );
|
||||
ADD( ConfOption( "MinTNSToHideNotes", MovePref<TapNoteScore>, "TNS_None", "TNS_HitMine", "TNS_AvoidMine", "TNS_CheckpointMiss", "TNS_Miss", "TNS_W5", "TNS_W4", "TNS_W3", "TNS_W2", "TNS_W1", "TNS_CheckpointHit"));
|
||||
|
||||
ADD( ConfOption( "ProfileSortOrderAscending", MovePref<bool>, "No", "Yes") );
|
||||
g_ConfOptions.back().m_iEffects = OPT_APPLY_PROFILES;
|
||||
ADD( ConfOption( "ProfileSortOrder", MovePref<ProfileSortOrder>, "Priority", "Recent", "Alphabetical") );
|
||||
g_ConfOptions.back().m_sPrefName = "ProfileSortOrder";
|
||||
g_ConfOptions.back().m_iEffects = OPT_APPLY_PROFILES;
|
||||
|
||||
// Graphic options
|
||||
ADD( ConfOption( "Windowed", MovePref<bool>, "Full Screen", "Windowed" ) );
|
||||
@@ -986,7 +990,8 @@ static const char *OptEffectNames[] = {
|
||||
"ChangeGame",
|
||||
"ApplySound",
|
||||
"ApplySong",
|
||||
"ApplyAspectRatio"
|
||||
"ApplyAspectRatio",
|
||||
"ApplyProfiles"
|
||||
};
|
||||
XToString( OptEffect );
|
||||
StringToX( OptEffect );
|
||||
|
||||
@@ -13,7 +13,8 @@ enum OptEffect
|
||||
OPT_APPLY_SOUND = (1<<4),
|
||||
OPT_APPLY_SONG = (1<<5),
|
||||
OPT_APPLY_ASPECT_RATIO = (1<<6),
|
||||
NUM_OptEffect = 7,
|
||||
OPT_APPLY_PROFILES = (1<<7),
|
||||
NUM_OptEffect = 8,
|
||||
OptEffect_Invalid = MAX_OPTIONS+1
|
||||
};
|
||||
const RString& OptEffectToString( OptEffect e );
|
||||
|
||||
Reference in New Issue
Block a user