mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-07-02 13:01:18 +12:00
GameList: Allow sorting by more columns (#1571)
This commit is contained in:
parent
2eec6b44c3
commit
f3fe6f3455
4 changed files with 84 additions and 18 deletions
|
@ -464,5 +464,34 @@ namespace iosu
|
||||||
return static_cast<IOSUModule*>(&sIOSUModuleNNPDM);
|
return static_cast<IOSUModule*>(&sIOSUModuleNNPDM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool GameListStat::LastPlayDate::operator<(const LastPlayDate& b) const
|
||||||
|
{
|
||||||
|
const auto& a = *this;
|
||||||
|
|
||||||
|
if(a.year < b.year)
|
||||||
|
return true;
|
||||||
|
if(a.year > b.year)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// same year
|
||||||
|
if(a.month < b.month)
|
||||||
|
return true;
|
||||||
|
if(a.month > b.month)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// same year and month
|
||||||
|
return a.day < b.day;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GameListStat::LastPlayDate::operator==(const LastPlayDate& b) const
|
||||||
|
{
|
||||||
|
const auto& a = *this;
|
||||||
|
return a.year == b.year &&
|
||||||
|
a.month == b.month &&
|
||||||
|
a.day == b.day;
|
||||||
|
}
|
||||||
|
std::weak_ordering GameListStat::LastPlayDate::operator<=>(const LastPlayDate& b) const = default;
|
||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,11 +21,15 @@ namespace iosu
|
||||||
/* Helper for UI game list */
|
/* Helper for UI game list */
|
||||||
struct GameListStat
|
struct GameListStat
|
||||||
{
|
{
|
||||||
struct
|
struct LastPlayDate
|
||||||
{
|
{
|
||||||
uint32 year; // if 0 -> never played
|
uint32 year; // if 0 -> never played
|
||||||
uint32 month;
|
uint32 month;
|
||||||
uint32 day;
|
uint32 day;
|
||||||
|
|
||||||
|
bool operator<(const LastPlayDate& b) const;
|
||||||
|
bool operator==(const LastPlayDate& b) const;
|
||||||
|
std::weak_ordering operator<=>(const LastPlayDate& b) const;
|
||||||
}last_played;
|
}last_played;
|
||||||
uint32 numMinutesPlayed;
|
uint32 numMinutesPlayed;
|
||||||
};
|
};
|
||||||
|
|
|
@ -485,25 +485,57 @@ static inline int order_to_int(const std::weak_ordering &wo)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxGameList::SortComparator(uint64 titleId1, uint64 titleId2, SortData* sortData)
|
std::weak_ordering wxGameList::SortComparator(uint64 titleId1, uint64 titleId2, SortData* sortData)
|
||||||
{
|
{
|
||||||
const auto isFavoriteA = GetConfig().IsGameListFavorite(titleId1);
|
auto titleLastPlayed = [](uint64_t id)
|
||||||
const auto isFavoriteB = GetConfig().IsGameListFavorite(titleId2);
|
{
|
||||||
const auto& name1 = GetNameByTitleId(titleId1);
|
iosu::pdm::GameListStat playTimeStat{};
|
||||||
const auto& name2 = GetNameByTitleId(titleId2);
|
iosu::pdm::GetStatForGamelist(id, playTimeStat);
|
||||||
|
return playTimeStat;
|
||||||
|
};
|
||||||
|
|
||||||
if(sortData->dir > 0)
|
auto titlePlayMinutes = [](uint64_t id)
|
||||||
return order_to_int(std::tie(isFavoriteB, name1) <=> std::tie(isFavoriteA, name2));
|
{
|
||||||
else
|
iosu::pdm::GameListStat playTimeStat;
|
||||||
return order_to_int(std::tie(isFavoriteB, name2) <=> std::tie(isFavoriteA, name1));
|
if (!iosu::pdm::GetStatForGamelist(id, playTimeStat))
|
||||||
|
return 0u;
|
||||||
|
return playTimeStat.numMinutesPlayed;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto titleRegion = [](uint64_t id)
|
||||||
|
{
|
||||||
|
return CafeTitleList::GetGameInfo(id).GetRegion();
|
||||||
|
};
|
||||||
|
|
||||||
|
switch(sortData->column)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case ColumnName:
|
||||||
|
{
|
||||||
|
const auto isFavoriteA = GetConfig().IsGameListFavorite(titleId1);
|
||||||
|
const auto isFavoriteB = GetConfig().IsGameListFavorite(titleId2);
|
||||||
|
const auto nameA = GetNameByTitleId(titleId1);
|
||||||
|
const auto nameB = GetNameByTitleId(titleId2);
|
||||||
|
return std::tie(isFavoriteB, nameA) <=> std::tie(isFavoriteA, nameB);
|
||||||
|
}
|
||||||
|
case ColumnGameStarted:
|
||||||
|
return titleLastPlayed(titleId1).last_played <=> titleLastPlayed(titleId2).last_played;
|
||||||
|
case ColumnGameTime:
|
||||||
|
return titlePlayMinutes(titleId1) <=> titlePlayMinutes(titleId2);
|
||||||
|
case ColumnRegion:
|
||||||
|
return titleRegion(titleId1) <=> titleRegion(titleId2);
|
||||||
|
case ColumnTitleID:
|
||||||
|
return titleId1 <=> titleId2;
|
||||||
|
}
|
||||||
|
// unreachable
|
||||||
|
cemu_assert_debug(false);
|
||||||
|
return std::weak_ordering::less;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxGameList::SortFunction(wxIntPtr item1, wxIntPtr item2, wxIntPtr sortData)
|
int wxGameList::SortFunction(wxIntPtr item1, wxIntPtr item2, wxIntPtr sortData)
|
||||||
{
|
{
|
||||||
const auto sort_data = (SortData*)sortData;
|
const auto sort_data = (SortData*)sortData;
|
||||||
const int dir = sort_data->dir;
|
return sort_data->dir * order_to_int(sort_data->thisptr->SortComparator((uint64)item1, (uint64)item2, sort_data));
|
||||||
|
|
||||||
return sort_data->thisptr->SortComparator((uint64)item1, (uint64)item2, sort_data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxGameList::SortEntries(int column)
|
void wxGameList::SortEntries(int column)
|
||||||
|
@ -530,8 +562,9 @@ void wxGameList::SortEntries(int column)
|
||||||
case ColumnGameTime:
|
case ColumnGameTime:
|
||||||
case ColumnGameStarted:
|
case ColumnGameStarted:
|
||||||
case ColumnRegion:
|
case ColumnRegion:
|
||||||
|
case ColumnTitleID:
|
||||||
{
|
{
|
||||||
SortData data{ this, column, s_direction };
|
SortData data{ this, ItemColumns{column}, s_direction };
|
||||||
SortItems(SortFunction, (wxIntPtr)&data);
|
SortItems(SortFunction, (wxIntPtr)&data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1049,7 +1082,7 @@ void wxGameList::OnClose(wxCloseEvent& event)
|
||||||
|
|
||||||
int wxGameList::FindInsertPosition(TitleId titleId)
|
int wxGameList::FindInsertPosition(TitleId titleId)
|
||||||
{
|
{
|
||||||
SortData data{ this, s_last_column, s_direction };
|
SortData data{ this, ItemColumns{s_last_column}, s_direction };
|
||||||
const auto itemCount = GetItemCount();
|
const auto itemCount = GetItemCount();
|
||||||
if (itemCount == 0)
|
if (itemCount == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -68,7 +68,7 @@ private:
|
||||||
inline static const wxColour kSecondColor{ 0xFDF9F2 };
|
inline static const wxColour kSecondColor{ 0xFDF9F2 };
|
||||||
void UpdateItemColors(sint32 startIndex = 0);
|
void UpdateItemColors(sint32 startIndex = 0);
|
||||||
|
|
||||||
enum ItemColumns
|
enum ItemColumns : int
|
||||||
{
|
{
|
||||||
ColumnHiddenName = 0,
|
ColumnHiddenName = 0,
|
||||||
ColumnIcon,
|
ColumnIcon,
|
||||||
|
@ -89,12 +89,12 @@ private:
|
||||||
struct SortData
|
struct SortData
|
||||||
{
|
{
|
||||||
wxGameList* thisptr;
|
wxGameList* thisptr;
|
||||||
int column;
|
ItemColumns column;
|
||||||
int dir;
|
int dir;
|
||||||
};
|
};
|
||||||
|
|
||||||
int FindInsertPosition(TitleId titleId);
|
int FindInsertPosition(TitleId titleId);
|
||||||
int SortComparator(uint64 titleId1, uint64 titleId2, SortData* sortData);
|
std::weak_ordering SortComparator(uint64 titleId1, uint64 titleId2, SortData* sortData);
|
||||||
static int SortFunction(wxIntPtr item1, wxIntPtr item2, wxIntPtr sortData);
|
static int SortFunction(wxIntPtr item1, wxIntPtr item2, wxIntPtr sortData);
|
||||||
|
|
||||||
wxTimer* m_tooltip_timer;
|
wxTimer* m_tooltip_timer;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue